{"record":{"id":"a2f98e61690fa3a6","repo":"toeverything/AFFiNE","slug":"access-token-expired","errorCode":"ACCESS_TOKEN_EXPIRED","errorMessage":"ACCESS_TOKEN_EXPIRED","messagePattern":"ACCESS_TOKEN_EXPIRED","errorType":"error_code","errorClass":"SessionAccessTokenError","httpStatus":401,"severity":"error","filePath":"packages/backend/server/src/core/auth/access-token.ts","lineNumber":80,"sourceCode":"    }\n    throw new AuthSessionTemporarilyUnavailable();\n  }\n\n  async verify(token: string): Promise<AuthSessionPrincipal> {\n    const keyId = authSessionAccessTokenKeyId(token);\n    if (!keyId) {\n      throw new SessionAccessTokenError('ACCESS_TOKEN_INVALID');\n    }\n    const key = await this.keys.verify(keyId);\n    if (!key) throw new SessionAccessTokenError('ACCESS_TOKEN_INVALID');\n    const verified = verifyAuthSessionAccessToken(\n      token,\n      keyId,\n      key.secret,\n      Math.floor(Date.now() / 1000)\n    );\n    if (verified.status !== 'valid') {\n      throw new SessionAccessTokenError(\n        verified.status === 'expired'\n          ? 'ACCESS_TOKEN_EXPIRED'\n          : 'ACCESS_TOKEN_INVALID'\n      );\n    }\n    const { authSessionId, userId } = verified;\n    if (!authSessionId || !userId) {\n      throw new SessionAccessTokenError('ACCESS_TOKEN_INVALID');\n    }\n    const authSession = await this.models.authSession.get(authSessionId);\n    if (!authSession || authSession.userSession.userId !== userId) {\n      throw new SessionAccessTokenError('ACCESS_TOKEN_INVALID');\n    }\n    if (authSession.revokedAt) {\n      throw new SessionAccessTokenError('AUTH_SESSION_REVOKED');\n    }\n    const now = new Date();\n    if (","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/b4c8548c09da21b2898443559a5b846f0ccf5dd8/packages/backend/server/src/core/auth/access-token.ts#L62-L98","documentation":"In verify(), after the key id is parsed and the signing key is loaded, verifyAuthSessionAccessToken is checked; any status other than 'valid' that isn't 'expired' maps to ACCESS_TOKEN_INVALID, i.e. the token failed signature/structural verification against the retrieved key secret.","triggerScenarios":"Thrown at packages/backend/server/src/core/auth/access-token.ts:80 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["The access token has expired — call the refresh/session endpoint to get a new token before retrying.","Implement automatic token refresh on ACCESS_TOKEN_EXPIRED responses instead of forcing the user to sign in again.","Check client clock skew; a badly skewed clock can make valid tokens appear expired."],"exampleFix":"if (res.status === 401 && body.includes('ACCESS_TOKEN_EXPIRED')) {\n  await refreshSession(); // POST /api/auth/session/refresh\n  return retry(originalRequest);\n}","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"b4c8548c09da21b2898443559a5b846f0ccf5dd8","analyzedAt":"2026-08-18T21:16:52.546Z","contentChangedAt":"2026-08-18T21:16:52.546Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}