{"record":{"id":"7b17bae12a687db5","repo":"toeverything/AFFiNE","slug":"access-token-invalid","errorCode":"access_token_invalid","errorMessage":"The access token is invalid.","messagePattern":"The access token is invalid\\.","errorType":"exception","errorClass":"AuthSessionHttpError","httpStatus":401,"severity":"error","filePath":"packages/backend/server/src/core/auth/guard.ts","lineNumber":144,"sourceCode":"    const result = await this.resolveRequestSession(req, res, isPublic);\n    return result?.session ?? null;\n  }\n\n  private async resolveRequestSession(\n    req: Request,\n    res?: Response,\n    isPublic = false\n  ): Promise<AuthenticatedRequestSession | null> {\n    const bearer = req.headers.authorization\n      ? extractTokenFromHeader(req.headers.authorization)\n      : undefined;\n    if (bearer && isLikelyJwt(bearer)) {\n      try {\n        const session = await this.signInWithJwt(req, bearer, res, isPublic);\n        return session ? { type: 'jwt', session } : null;\n      } catch (err) {\n        if (err instanceof SessionAccessTokenError) {\n          throw new AuthSessionHttpError(err.code);\n        }\n        throw err;\n      }\n    }\n\n    const session = await this.signInWithCookie(req, res, isPublic);\n    return session ? { type: 'cookie_session', session } : null;\n  }\n\n  async signInWithJwt(\n    req: Request,\n    token: string,\n    res?: Response,\n    isPublic = false\n  ): Promise<Session | null> {\n    if (req.session && req.authType === 'jwt') return req.session;\n    const session = await this.accessTokens.verify(token);\n    const versionAllowed = await this.checkUserSessionClientVersion(","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/26c515e050211269e911f7d9cfe162a26c83ed98/packages/backend/server/src/core/auth/guard.ts#L126-L162","documentation":"Surfaced in `resolveRequestSession` when `signInWithJwt` → `AccessTokenService.verify` throws `SessionAccessTokenError('ACCESS_TOKEN_INVALID')`, re-wrapped as `AuthSessionHttpError`. Triggers include: the token's key id is unknown/retired, signature verification failed, the token lacks `authSessionId`/`userId`, the referenced auth session or user does not match, or the user was not found. HTTP 401.","triggerScenarios":"Presenting a JWT whose signing key was deleted, a tampered token, a token minted for a different user/session, or one referencing an auth session that no longer exists.","commonSituations":"Signing keys were rotated/removed and the client still holds an old token, a token was corrupted in transit or storage, or the user/account was deleted.","solutions":["Discard the stored access token and re-authenticate (or refresh via the refresh token).","If keys were rotated, ensure clients refresh tokens after rotation completes.","Verify the token source is not truncating or re-encoding the JWT."],"exampleFix":"// before\nfetch(url, { headers: { authorization: `Bearer ${staleToken}` } }); // 401 access_token_invalid\n\n// after\nconst { accessToken } = await refreshSession(refreshToken);\nfetch(url, { headers: { authorization: `Bearer ${accessToken}` } });","handlingStrategy":"try-catch","validationCode":"function decodeJwtExp(token: string): number | null {\n  try {\n    const p = JSON.parse(atob(token.split('.')[1]));\n    return typeof p.exp === 'number' ? p.exp : null;\n  } catch { return null; }\n}\n// detect structurally invalid tokens before sending\nif (!/^[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+$/.test(token)) {\n  await discardAndReauth();\n}","typeGuard":"function looksLikeJwt(v: string): boolean {\n  return /^[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+$/.test(v);\n}","tryCatchPattern":"if (res.status === 401 && body.code === 'access_token_invalid') {\n  // token is structurally/signature invalid or key removed — cannot refresh, re-auth\n  await signOut();\n  redirect('/sign-in');\n}","preventionTips":["Do not reuse access tokens across key rotations — refresh after rotation.","Store tokens verbatim; avoid truncation, re-encoding, or URL-decoding twice.","On 401 access_token_invalid, discard the token and re-authenticate (refresh will also fail)."],"tags":["authentication","jwt","access-token","invalid"],"backgroundTag":null,"analyzedSha":"26c515e050211269e911f7d9cfe162a26c83ed98","analyzedAt":"2026-08-12T13:15:16.447Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}