{"record":{"id":"9e7a916e10f71f45","repo":"bytedance/deer-flow","slug":"user-not-found-9e7a91","errorCode":null,"errorMessage":"User not found","messagePattern":"User not found","errorType":"http","errorClass":"HTTPException","httpStatus":401,"severity":"error","filePath":"backend/app/gateway/langgraph_auth.py","lineNumber":92,"sourceCode":"        return AUTH_DISABLED_USER_ID\n\n    token = request.cookies.get(\"access_token\")\n    if not token:\n        raise Auth.exceptions.HTTPException(\n            status_code=401,\n            detail=\"Not authenticated\",\n        )\n\n    payload = decode_token(token)\n    if isinstance(payload, TokenError):\n        raise Auth.exceptions.HTTPException(\n            status_code=401,\n            detail=\"Invalid token\",\n        )\n\n    user = await get_local_provider().get_user(payload.sub)\n    if user is None:\n        raise Auth.exceptions.HTTPException(\n            status_code=401,\n            detail=\"User not found\",\n        )\n    if user.token_version != payload.ver:\n        raise Auth.exceptions.HTTPException(\n            status_code=401,\n            detail=\"Token revoked (password changed)\",\n        )\n\n    return payload.sub\n\n\n@auth.on\nasync def add_owner_filter(ctx: Auth.types.AuthContext, value: dict):\n    \"\"\"Inject user_id metadata on writes; filter by user_id on reads.\n\n    Gateway stores thread ownership as ``metadata.user_id``.\n    This handler ensures LangGraph Server enforces the same isolation.","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/app/gateway/langgraph_auth.py#L74-L110","documentation":"The JWT decoded successfully, but the `sub` claim points at a user that no longer exists in the local user provider (`get_user(payload.sub)` returned None). The token itself is structurally valid; the account behind it was deleted. HTTP 401 'User not found'.","triggerScenarios":"Logging in, then having the account deleted by an admin or a user-management script, then reusing the still-valid cookie; a rebuilt/reset user database where user IDs changed while cookies survived; importing/migrating users with new IDs.","commonSituations":"User database wiped during dev iterations while browsers keep cookies; account deletion flows that don't invalidate outstanding cookies; test environments with ephemeral user stores.","solutions":["Clear the `access_token` cookie and log in again as an existing user","If the user should exist, verify the user store backing `get_local_provider()` actually contains that user id","After account deletion flows, proactively clear auth cookies server-side or bump token_version so stale cookies fail fast with a clearer path"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await call();\n} catch (e) {\n  if (e.status === 401 && e.detail === 'User not found') {\n    clearAuthCookie();\n    redirect('/login'); // account is gone; re-auth as a real user\n  } else throw e;\n}","preventionTips":["When deleting users, also clear their auth cookies or bump token_version","In dev, clear cookies after resetting the user database","Treat 'User not found' as terminal for the session — retrying cannot succeed"],"tags":["auth","http-401","user-management","stale-cookie"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}