{"record":{"id":"75722b62b0024b02","repo":"Dokploy/dokploy","slug":"unauthorized-75722b","errorCode":null,"errorMessage":"Unauthorized","messagePattern":"Unauthorized","errorType":"http","errorClass":null,"httpStatus":401,"severity":"warning","filePath":"apps/dokploy/pages/api/[...trpc].ts","lineNumber":11,"sourceCode":"import { validateRequest } from \"@dokploy/server\";\nimport { createOpenApiNextHandler } from \"@dokploy/trpc-openapi\";\nimport type { NextApiRequest, NextApiResponse } from \"next\";\nimport { appRouter } from \"@/server/api/root\";\nimport { createTRPCContext } from \"@/server/api/trpc\";\n\nconst handler = async (req: NextApiRequest, res: NextApiResponse) => {\n\tconst { session, user } = await validateRequest(req);\n\n\tif (!user || !session) {\n\t\tres.status(401).json({ message: \"Unauthorized\" });\n\t\treturn;\n\t}\n\n\t// @ts-ignore\n\treturn createOpenApiNextHandler({\n\t\trouter: appRouter,\n\t\tcreateContext: createTRPCContext,\n\t\tonError:\n\t\t\tprocess.env.NODE_ENV === \"development\"\n\t\t\t\t? ({ path, error }: { path: string | undefined; error: Error }) => {\n\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t`❌ OpenAPI failed on ${path ?? \"<no-path>\"}: ${error.message}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t})(req, res);\n};\n","sourceCodeStart":1,"sourceCodeEnd":29,"githubUrl":"https://github.com/Dokploy/dokploy/blob/546686ea3587f12ec5652217dedd9f7960fb6d15/apps/dokploy/pages/api/[...trpc].ts#L1-L29","documentation":"The catch-all tRPC handler for /api/trpc validates the request with validateRequest (Lucia session); if there is no user or session it responds 401 {message:'Unauthorized'} before mounting the tRPC open-api handler. This is an auth gate, not a tRPC error.","triggerScenarios":"API call without a valid session cookie; expired session; cookie not sent (cross-origin fetch without credentials); user deleted/deactivated between issue and request.","commonSituations":"Session expired while the dashboard sat open; curl/Postman call missing the auth cookie; reverse proxy stripping cookies; clock skew invalidating the session.","solutions":["Log in again to obtain a fresh session cookie","For programmatic clients, authenticate first and forward the session cookie (credentials: 'include' for cross-origin)","Check the proxy forwards the Cookie header","If sessions constantly expire early, verify server clock and session secret stability"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const { session, user } = await validateRequest(req);\nif (!user || !session) return res.status(401).json({ message: 'Unauthorized' });","typeGuard":null,"tryCatchPattern":"const r = await fetch('/api/trpc/...', { credentials: 'include' });\nif (r.status === 401) { window.location.href = '/login'; }","preventionTips":["Always send credentials: 'include' for cross-origin API calls","Handle 401 globally in the client with a redirect to login","Keep session cookie SameSite/proxy settings aligned with your deployment"],"tags":["auth","unauthorized","session","trpc","nextjs"],"backgroundTag":"session-unauthorized","analyzedSha":"546686ea3587f12ec5652217dedd9f7960fb6d15","analyzedAt":"2026-08-27T05:18:58.095Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}