nextauthjs/next-auth · error · UnknownAction

Cannot parse action at ${pathname}

Error message

Cannot parse action at ${pathname}

What it means

parseActionAndProviderId matches the request pathname against the configured basePath using the regex ^{base}(.+); if the pathname does not extend the base path (no trailing segment), the match fails and UnknownAction is thrown. It means the URL carries no actionable segment after the auth base path.

Source

Thrown at packages/core/src/lib/utils/web.ts:127

/** Web compatible method to create a random string of a given length */
export function randomString(size: number) {
  const i2hex = (i: number) => ("0" + i.toString(16)).slice(-2)
  const r = (a: string, i: number): string => a + i2hex(i)
  const bytes = crypto.getRandomValues(new Uint8Array(size))
  return Array.from(bytes).reduce(r, "")
}

/** @internal Parse the action and provider id from a URL pathname. */
export function parseActionAndProviderId(
  pathname: string,
  base: string
): {
  action: AuthAction
  providerId?: string
} {
  const a = pathname.match(new RegExp(`^${base}(.+)`))

  if (a === null) throw new UnknownAction(`Cannot parse action at ${pathname}`)

  const actionAndProviderId = a.at(-1)!

  const b = actionAndProviderId.replace(/^\//, "").split("/").filter(Boolean)

  if (b.length !== 1 && b.length !== 2)
    throw new UnknownAction(`Cannot parse action at ${pathname}`)

  const [action, providerId] = b

  if (!isAuthAction(action))
    throw new UnknownAction(`Cannot parse action at ${pathname}`)

  if (
    providerId &&
    !["signin", "callback", "webauthn-options"].includes(action)
  )
    throw new UnknownAction(`Cannot parse action at ${pathname}`)

View on GitHub (pinned to a1a16a5a77)

Solutions

  1. Set config.basePath to the full prefix of the auth route (e.g. "/api/auth") so it matches incoming URLs
  2. Request a real action endpoint like /api/auth/session rather than the bare base path
  3. Check proxy/rewrite rules so the original pathname is preserved

Example fix

// before
export const { handlers } = NextAuth({ basePath: "/auth" }) // routes at /api/auth/*
// after
export const { handlers } = NextAuth({ basePath: "/api/auth" })
Defensive patterns

Strategy: validation

Validate before calling

const base = "/api/auth";
if (!pathname.startsWith(base) || pathname === base) throw new Error(`URL must include an action after ${base}`);

Type guard

null

Try / catch

try { return await handle(req) } catch (e) { if (String(e.message).startsWith("Cannot parse action")) return new Response("Not Found", { status: 404 }); throw e; }

Prevention

When it happens

Trigger: Requesting exactly /api/auth (basePath with no action suffix), or a URL where basePath is misconfigured so the regex does not match, e.g. basePath set to /auth while requests come to /api/auth.

Common situations: basePath option not matching the actual mounted route (AuthHandler mounted at /api/auth/[...action] but basePath left as default or vice versa); proxies stripping or rewriting the path.

Related errors


AI-assisted analysis of nextauthjs/next-auth@a1a16a5a77 (2026-08-28). Data as JSON: /api/errors/08f7865d2a7921b9. Report an issue: GitHub.