{"record":{"id":"4bf4a0ef1d750fde","repo":"payloadcms/payload","slug":"unauthorized-4bf4a0","errorCode":null,"errorMessage":"Unauthorized","messagePattern":"Unauthorized","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/tanstack-start/src/utilities/serverAdapter.server.ts","lineNumber":99,"sourceCode":"  },\n\n  permanentRedirect: (path: string) => {\n    // TanStack Router does not have a separate permanent redirect primitive;\n    // fall back to a regular redirect so existing behavior is preserved.\n    // eslint-disable-next-line @typescript-eslint/only-throw-error\n    throw redirect({ to: path })\n  },\n\n  forbidden: () => {\n    // TanStack Router does not have a dedicated forbidden() helper; surface\n    // a generic error so the request boundary still terminates the request.\n    throw new Error('Forbidden')\n  },\n\n  unauthorized: () => {\n    // TanStack Router does not have a dedicated unauthorized() helper; surface\n    // a generic error so the request boundary still terminates the request.\n    throw new Error('Unauthorized')\n  },\n\n  setCookie: (name: string, value: string, options?: CookieOptions) => {\n    setResponseHeader('Set-Cookie', serializeCookie(name, value, options))\n  },\n}\n\n/**\n * Navigation requested during an admin page render, recorded by\n * `createPageRenderServerAdapter`. The admin-page server function reads this\n * after `renderServerComponent` resolves.\n */\nexport type PageNavIntent = {\n  type?: 'notFound' | 'redirect'\n  url?: string\n}\n\n/**","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/tanstack-start/src/utilities/serverAdapter.server.ts#L81-L117","documentation":"A plain Error('Unauthorized') thrown by the TanStack Start server adapter's unauthorized() helper. TanStack Router lacks a dedicated unauthorized primitive, so the adapter throws a generic error when framework code calls adapter.unauthorized() — typically because no user was resolved during an admin page render.","triggerScenarios":"The admin page-render pipeline calls adapter.unauthorized() because req.user is null during a TanStack Start server render (no session, expired session, or auth not yet resolved).","commonSituations":"Reaching a guarded admin route without a session cookie; session expired between requests; auth strategy not wired into the TanStack Start adapter; SSR happening before cookie parsing.","solutions":["Ensure the session cookie is sent and parsed before the guarded route renders.","Configure the auth strategy so req.user is populated for the TanStack Start adapter.","Handle this generic error in the error boundary to redirect to login / render a 401 page."],"exampleFix":"// before\nunauthorized: () => {\n  throw new Error('Unauthorized')\n},\n\n// after\nimport { UnauthorizedError } from 'payload'\nunauthorized: () => {\n  throw new UnauthorizedError()\n},","handlingStrategy":"try-catch","validationCode":"function isAuthenticated(user: unknown): user is { id: string } {\n  return Boolean(user)\n}\n\nif (!isAuthenticated(req.user)) {\n  // handle before the adapter calls unauthorized()\n  redirect('/login')\n}","typeGuard":"function isAdapterUnauthorized(err: unknown): err is Error {\n  return err instanceof Error && err.message === 'Unauthorized'\n}","tryCatchPattern":"try {\n  await renderAdminPage()\n} catch (err) {\n  if (isAdapterUnauthorized(err)) {\n    redirectToLogin()\n    return\n  }\n  throw err\n}","preventionTips":["Ensure the session cookie is parsed before SSR so req.user is populated.","Map this generic error in your error boundary to a 401 / login redirect.","Consider replacing the bare Error with UnauthorizedError for type-narrowable handling."],"tags":["tanstack-start","server-adapter","unauthorized","auth","framework"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}