#WorkOS + Convex + Next.js

14 messages · Page 1 of 1 (latest)

solemn iron
#

I'm using WorkoS component with Convex in Next.js.
In development works amazing, but in production it redirects me to WorkOS auth page every time I navigate.

I'm logging the user in my proxy.ts and I get this:

const {
    session,
    headers: authkitHeaders,
    authorizationUrl,
  } = await authkit(request, {
    debug: true,
  });

  console.log("session", session);
  console.log("session user", session.user);

And the output is:

session { user: null }
session user null

And it craetes a 307 Temporary redirect to:
https://api.workos.com/user_management/authorize?[REDACTED]

What could be the issue?

floral pivotBOT
#

Hi @solemn iron. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

This sounds like an AuthKit / session issue on the WorkOS side rather than Convex itself: AuthKit is not finding a valid session in production, so authkit() returns { user: null } and (correctly) issues a 307 redirect to the WorkOS authorize URL.

From the Convex + AuthKit docs and Discord threads, the most common causes when dev works but prod always redirects are:

  1. Prod WorkOS env vars not set / mismatched

Make sure your production .env (and your hosting provider’s env) has the production values, not the dev ones:

WORKOS_CLIENT_ID="client_01..."      # prod client
WORKOS_API_KEY="sk_live_..."         # prod API key
WORKOS_COOKIE_PASSWORD="32+ chars"
NEXT_PUBLIC_WORKOS_REDIRECT_URI="<https://your-domain.com/callback">

And that these match exactly what’s configured in the WorkOS Dashboard for that application (redirect URI, client ID, etc.). [Config dev/prod]

  1. Cookie / domain / HTTPS issues

AuthKit stores the session in an encrypted cookie. If that cookie can’t be read in production, authkit() will always see user: null and redirect.

Check:

  • WORKOS_COOKIE_PASSWORD is identical between the server that sets the cookie and the one reading it, and is at least 32 chars. [Config dev/prod]
  • Your production domain matches what WorkOS expects (no mismatch between trydocufy.com vs www.trydocufy.com, etc.).
  • You’re on HTTPS in prod so cookies with Secure are actually sent.
  1. Using the wrong WorkOS app (dev vs prod)

It’s easy to have:

  • Dev: client_01... + sk_test_...
  • Prod: still pointing at the dev client or dev redirect URI
#

In that case, the login flow “works” in dev, but in prod the callback / cookie is for a different origin or app, so authkit() never sees a valid session and keeps redirecting. The Convex docs explicitly call out separate WORKOS_CLIENT_ID per deployment. [Config dev/prod]

  1. AuthKit middleware / routes not wired correctly in prod

For Next.js, Convex’s docs assume you’re using the standard AuthKit setup:

  • middleware.ts with authkitMiddleware({ middlewareAuth: { enabled: true, ... } })
  • app/callback/route.ts using handleAuth()
  • app/sign-in/route.ts and app/sign-up/route.ts using getSignInUrl() [Next.js guide]

If any of these routes are missing or misconfigured only in prod (e.g. wrong NEXT_PUBLIC_WORKOS_REDIRECT_URI), the session won’t be established and authkit() will keep redirecting.


Because your logs show session { user: null } and an immediate 307 to .../authorize, the root cause is definitely “AuthKit doesn’t see a valid session cookie in production.” The knowledge sources don’t include a step‑by‑step for debugging authkit() itself, so I can’t be more specific than:

  • Double‑check all WorkOS env vars and redirect URIs for the production deployment.
  • Confirm the session cookie is actually being set and sent back on subsequent requests in prod.
  • Ensure WORKOS_COOKIE_PASSWORD and domain/HTTPS settings are correct.

If you can share which template / setup you followed (e.g. template-convex-nextjs-authkit) and confirm whether your prod env vars differ from dev, that’s usually where this kind of issue has been resolved in the past.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@solemn iron Kapa.ai is still learning and improving, please let me know how I did by reacting below.

solemn iron
#

I already checked all that. As the screenshot shows @floral pivot the login works, the navigation to dashboard, works, but if I navigate ONCE more, the session gets lost and I get kicked out by a 307 error

floral pivotBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

The knowledge sources don’t contain a report of exactly “works for one navigation, then every further navigation 307s,” but they do describe very similar “works in dev, breaks / logs out in prod” AuthKit + Next.js behaviors. I’ll stick to what’s documented and what’s been seen in those threads.

Given:

  • authkit(request, { debug: true }) returns session { user: null } on that second navigation
  • AuthKit then issues a 307 to .../user_management/authorize
  • First login + first navigation to dashboard do work

this means: on that second navigation, AuthKit is not seeing a valid session cookie anymore, even though it did just moments before. That’s why it’s redirecting.

From the Convex + WorkOS docs and Discord thread, the production‑only “session disappears” issues have almost always boiled down to one of:

  1. Cookie not being sent on some requests

AuthKit’s session is stored in a cookie. If that cookie is:

  • scoped to a different domain (e.g. example.com vs www.example.com), or
  • not sent on some routes because of path / domain / HTTPS differences,

then some navigations will see session.user and others will see null, causing exactly the “sometimes logged in, sometimes 307” behavior.

The Convex docs emphasize that WORKOS_COOKIE_PASSWORD and redirect URI must be consistent and correctly configured per environment, but they don’t go into cookie flags in detail. [Config dev/prod]

  1. Prod vs dev WorkOS app / redirect URI mismatch

Even if you’ve checked env vars, a subtle mismatch like:

  • NEXT_PUBLIC_WORKOS_REDIRECT_URI using <https://your-domain.com/callback> but the app is actually served at <https://www.your-domain.com,> or
  • WorkOS Dashboard redirect URI not matching the exact origin you’re using in prod,
#

can result in a session cookie that’s not valid for the origin you’re navigating on, so subsequent navigations lose the session. [Config dev/prod]

  1. Middleware / matcher only running on some routes

If authkitMiddleware is only applied to some paths (via config.matcher), you can end up in a situation where:

  • First navigation hits a route where middleware runs, session is established, everything works.
  • Second navigation hits a route where middleware doesn’t run as expected, or runs with a different URL / headers context, and authkit() doesn’t see the cookie → user: null → 307.

The Convex docs show the recommended matcher for Next.js: [Next.js guide]

export const config = {
  matcher: [
    '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)',
    '/(api|trpc)(.*)',
  ],
};

If your matcher differs in prod (or you’re deploying under a different base path), that can cause inconsistent middleware behavior.


Because the sources don’t include a concrete “second navigation always logs me out” repro, I can’t point to a known bug or one‑line fix. All we can say with confidence from the docs and thread is:

  • The 307 is expected when authkit() sees session.user === null.
  • In your case, that means the AuthKit session cookie is not being read on that second navigation in production.
  • The likely culprits, based on prior issues, are cookie scope / domain / HTTPS, redirect URI / origin mismatch, or middleware not consistently running on all the routes you’re navigating to. [Config dev/prod; Next.js guide]
#

To move forward, the most reliable next step (and what Convex staff recommend in similar Discord threads) is to:

  • Reproduce the issue in a minimal repo (ideally starting from template-convex-nextjs-authkit), and
  • Compare your middleware.ts, NEXT_PUBLIC_WORKOS_REDIRECT_URI, and actual deployed domain, and
  • Inspect cookies in the browser devtools across the first and second navigations to confirm whether the AuthKit session cookie disappears or stops being sent.

If you can share which template you started from and the exact routes you’re navigating between, that’s the kind of detail Convex and WorkOS have used to track down these production‑only session issues in the past.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@solemn iron Kapa.ai is still learning and improving, please let me know how I did by reacting below.

solemn iron
#

I went into WorkOS and it says that the user session was Revoked. What could be the reason @floral pivot ?

floral pivotBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

The knowledge sources don’t explain specific WorkOS reasons for a session being marked “Revoked,” so I can’t say exactly why in your case.

From the Convex side, all we know is:

  • Convex relies on the WorkOS AuthKit session cookie and the JWT it issues.
  • When that session is no longer valid (expired or revoked), AuthKit will stop returning a user and will redirect back to WorkOS (307 to /user_management/authorize). [Debugging auth]

The docs and Discord threads focus on configuration issues (env vars, redirect URIs, aud claim, cookie password) and token freshness, but they don’t document WorkOS’ internal revocation logic or specific causes for “Revoked” status. [Config dev/prod; Debugging auth]

So, based only on these sources:

  • “Revoked” just means WorkOS has invalidated that session, so Convex will see the user as unauthenticated and you’ll get redirected.
  • The concrete reasons (manual logout, security policy, refresh behavior, etc.) are not described in the Convex docs; you’d need to check WorkOS’ own docs or support for the exact cause.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: