{"record":{"id":"c9d0cb8a5d3f3101","repo":"hcengineering/platform","slug":"missing-account-in-token","errorCode":null,"errorMessage":"Missing account in token","messagePattern":"Missing account in token","errorType":"http","errorClass":null,"httpStatus":401,"severity":"error","filePath":"services/payment/pod-payment/src/server.ts","lineNumber":212,"sourceCode":"    withLoginInfo,\n    withOwner,\n    (req: RequestWithAuth, res: Response) => {\n      if (provider === undefined || serviceToken === undefined) {\n        res.status(503).json({ error: 'Payment provider is not configured' })\n        return\n      }\n\n      void handleRequest(\n        ctx,\n        'create-subscription',\n        async (ctx) => {\n          const workspaceUuid = req.token?.workspace\n          const accountUuid = req.token?.account\n          const request = req.body as SubscribeRequest\n          const loginInfo = req.loginInfo as WorkspaceLoginInfo\n\n          if (accountUuid === undefined) {\n            res.status(401).json({ error: 'Missing account in token' })\n            return\n          }\n\n          if (workspaceUuid === undefined) {\n            res.status(401).json({ error: 'Missing workspace in token' })\n            return\n          }\n\n          if (loginInfo?.workspaceUrl === undefined) {\n            res.status(401).json({ error: 'Missing workspace url in login info' })\n            return\n          }\n\n          if (request.type === undefined || request.plan === undefined) {\n            res.status(400).json({ error: 'Missing required fields: type, plan' })\n            return\n          }\n","sourceCodeStart":194,"sourceCodeEnd":230,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/services/payment/pod-payment/src/server.ts#L194-L230","documentation":"The create-subscription route requires the authenticated token to carry an account UUID. If req.token.account is undefined the request is rejected with 401 'Missing account in token' because subscriptions must be attributed to an account.","triggerScenarios":"Auth token (JWT/session token) issued without an account claim; using a service/automation token that lacks account context; auth middleware decoded a token whose payload predates the account claim schema; corrupted or handcrafted token.","commonSituations":"Client using an old cached token minted before account claims were added; internal service-to-service calls using machine tokens; auth provider misconfiguration omitting the account claim.","solutions":["Re-authenticate to obtain a fresh token containing the account claim","Fix token issuance in the auth service to always include account in the payload","Verify the auth middleware populates req.token.account from the correct claim name","Check the client isn't sending a service-only token for user-scoped operations"],"exampleFix":"// before (token payload)\n{ \"workspace\": \"ws_1\" }\n// after\n{ \"workspace\": \"ws_1\", \"account\": \"acc_42\" }","handlingStrategy":"validation","validationCode":"const payload = decodeJwt(token)\nif (payload.account === undefined) {\n  throw new Error('Token is missing the account claim; re-authenticate')\n}","typeGuard":"function tokenHasAccount(token: { account?: string } | undefined): token is { account: string } {\n  return typeof token?.account === 'string' && token.account.length > 0\n}","tryCatchPattern":null,"preventionTips":["Ensure the auth service always includes account in token payloads","Refresh stale tokens cached before schema changes","Use user-scoped tokens (not service tokens) for subscription APIs","Unit-test token issuance to guarantee required claims"],"tags":["auth","jwt","http-401","token"],"backgroundTag":"missing-token-claim","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}