{"record":{"id":"01d874fc53a9408d","repo":"mastra-ai/mastra","slug":"invalid-token","errorCode":null,"errorMessage":"Invalid token","messagePattern":"Invalid token","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/auth/src/utils.ts","lineNumber":12,"sourceCode":"import jwt from 'jsonwebtoken';\nimport jwksClient from 'jwks-rsa';\n\nexport type JwtPayload = jwt.JwtPayload;\n\nexport async function decodeToken(accessToken: string) {\n  const decoded = jwt.decode(accessToken, { complete: true });\n  return decoded;\n}\n\nexport function getTokenIssuer(decoded: jwt.JwtPayload | null) {\n  if (!decoded) throw new Error('Invalid token');\n  if (!decoded.payload || typeof decoded.payload !== 'object') throw new Error('Invalid token payload');\n  if (!decoded.payload.iss) throw new Error('Invalid token header');\n  return decoded.payload.iss;\n}\n\nexport async function verifyHmac(accessToken: string, secret: string) {\n  const decoded = jwt.decode(accessToken, { complete: true });\n\n  if (!decoded) throw new Error('Invalid token');\n\n  return jwt.verify(accessToken, secret) as jwt.JwtPayload;\n}\n\nexport async function verifyJwks(accessToken: string, jwksUri: string) {\n  const decoded = jwt.decode(accessToken, { complete: true });\n\n  if (!decoded) throw new Error('Invalid token');\n","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/auth/src/utils.ts#L1-L30","documentation":"getTokenIssuer decodes an access token's issuer (iss claim) and throws 'Invalid token' when jwt.decode returned null — meaning the string could not be decoded as a JWT at all (malformed structure, not three dot-separated base64 segments, or undecodable payload). Related sibling throws cover a missing/non-object payload ('Invalid token payload') and a missing iss ('Invalid token header').","triggerScenarios":"Calling getTokenIssuer(decodeToken(accessToken)) where accessToken is not a valid JWT: garbage/truncated string, opaque token (e.g. a random API key), a token that was URL-corrupted, or decoding a token type jsonwebtoken's decode cannot parse.","commonSituations":"Clients sending the wrong credential type in the Authorization header, copy/paste truncation of tokens, tokens mangled by proxies/logging, or expecting an id_token but receiving an opaque refresh token.","solutions":["Log/inspect the raw accessToken received — confirm it looks like header.payload.signature","Fix the client/sender to transmit a real JWT (correct token type in the Authorization header)","Check for truncation/corruption in transit (headers split, whitespace, URL encoding issues)","Before calling, guard: const d = await decodeToken(t); if (!d) handle invalid token instead of throwing"],"exampleFix":"// before\nconst issuer = await getTokenIssuer(await decodeToken(token));\n// after\nconst decoded = await decodeToken(token);\nif (!decoded) throw new UnauthorizedError('Malformed token');\nconst issuer = getTokenIssuer(decoded);","handlingStrategy":"type-guard","validationCode":"/^eyJ[\\w-]+\\.[\\w-]+\\.[\\w-]*$/.test(token) // quick 3-part JWT shape check before decodeToken\nexport function looksLikeJwt(t: string) { return /^eyJ[\\w-]+\\.[\\w-]+\\.[\\w-]*$/.test(t); }","typeGuard":"export function isDecodedJwt(d: jwt.JwtPayload | null): d is jwt.JwtPayload {\n  return d != null && typeof d === 'object' && typeof d.iss === 'string';\n}\nconst decoded = await decodeToken(token);\nif (!isDecodedJwt(decoded)) throw new UnauthorizedError('Malformed or non-JWT credential');","tryCatchPattern":"try {\n  const issuer = await getTokenIssuer(await decodeToken(token));\n} catch (e) {\n  if (e instanceof Error && e.message === 'Invalid token') {\n    // token did not decode: return 401 'malformed token' instead of a 500\n  }\n  throw e;\n}","preventionTips":["Pre-check tokens with a 3-segment shape regex before decoding","Ensure clients send a real JWT, not opaque keys, in the Authorization header","Guard headers from truncation/corruption in proxies and gateways","Return 401 (client error) rather than letting this become a 500 on the server"],"tags":["jwt","auth","token","decoding"],"backgroundTag":"invalid-jwt-token","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}