{"record":{"id":"147f033f7cb3bcfe","repo":"eyaltoledano/claude-task-master","slug":"missing-tokens","errorCode":"MISSING_TOKENS","errorMessage":"'Server returned no encrypted tokens'","messagePattern":"'Server returned no encrypted tokens'","errorType":"exception","errorClass":"AuthenticationError","httpStatus":null,"severity":"error","filePath":"packages/tm-core/src/modules/auth/services/oauth-service.ts","lineNumber":364,"sourceCode":"\t\t\t\t\t\terrorData.message || `HTTP ${response.status}`,\n\t\t\t\t\t\t'POLL_FAILED'\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst data = (await response.json()) as FlowStatusResponse;\n\n\t\t\t\tif (!data.success) {\n\t\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t\tdata.message || 'Failed to check status',\n\t\t\t\t\t\t'POLL_FAILED'\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tswitch (data.status) {\n\t\t\t\t\tcase 'complete': {\n\t\t\t\t\t\t// Decrypt tokens using our private key\n\t\t\t\t\t\tif (!data.encrypted_tokens) {\n\t\t\t\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t\t\t\t'Server returned no encrypted tokens',\n\t\t\t\t\t\t\t\t'MISSING_TOKENS'\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst tokens = decryptTokens(\n\t\t\t\t\t\t\tdata.encrypted_tokens,\n\t\t\t\t\t\t\tthis.keyPair.privateKey\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tthis.logger.debug('Successfully decrypted authentication tokens');\n\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttoken: tokens.access_token,\n\t\t\t\t\t\t\trefreshToken: tokens.refresh_token,\n\t\t\t\t\t\t\tuserId: tokens.user_id,\n\t\t\t\t\t\t\temail: tokens.email,\n\t\t\t\t\t\t\texpiresAt: tokens.expires_in","sourceCodeStart":346,"sourceCodeEnd":382,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/packages/tm-core/src/modules/auth/services/oauth-service.ts#L346-L382","documentation":"MISSING_TOKENS is thrown when the poll reports status 'complete' but the response body lacks the `encrypted_tokens` field. The CLI decrypts tokens locally with an ephemeral keypair, so a 'complete' result without the encrypted payload is a server-side contract violation and cannot be recovered.","triggerScenarios":"`credentials()` polling receives `{success:true,status:'complete'}` but `data.encrypted_tokens` is undefined/null — the backend marked the flow complete without attaching the RSA-encrypted token payload.","commonSituations":"Backend version mismatch where the status endpoint no longer includes encrypted_tokens; a reverse proxy or response-transforming middleware stripping large fields; server bug when storing flow results; client pointed at an older API deployment.","solutions":["Retry `credentials()` to start a fresh flow with a new keypair — a transient server glitch is the most common cause.","Check that CLI and backend versions match (the status response schema may have changed); update @tm/core / the CLI.","Verify no proxy/middleware strips or truncates the response body (encrypted_tokens can be large).","Report persistent occurrences with the flow_id to the backend team — 'complete' without tokens is a server bug."],"exampleFix":"// before: assumes complete always carries tokens, hard failure\nconst creds = await oauthService.credentials();\n// after: handle MISSING_TOKENS with one retry\ntry {\n  return await oauthService.credentials();\n} catch (e) {\n  if (e instanceof AuthenticationError && e.code === 'MISSING_TOKENS') {\n    return oauthService.credentials(); // fresh flow regenerates keypair\n  }\n  throw e;\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":"function isCompleteWithTokens(d: FlowStatusResponse):\n  d is FlowStatusResponse & { status: 'complete'; encrypted_tokens: string } {\n  return d.status === 'complete' && typeof d.encrypted_tokens === 'string' && d.encrypted_tokens.length > 0;\n}","tryCatchPattern":"try {\n  return await oauthService.credentials();\n} catch (e) {\n  if (e instanceof AuthenticationError && e.code === 'MISSING_TOKENS') {\n    // fresh flow regenerates keypair and asks server for tokens again\n    return oauthService.credentials();\n  }\n  throw e;\n}","preventionTips":["Keep CLI/tm-core and backend deployments version-aligned.","Don't route auth API responses through response-transforming middleware.","Retry once automatically — a fresh flow usually resolves transient glitches.","Report persistent cases to the backend team with the flow_id."],"tags":["oauth","api-contract","server-bug","tokens"],"backgroundTag":"oauth-response-missing-tokens","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}