{"record":{"id":"1fb3c244cb1f6960","repo":"eyaltoledano/claude-task-master","slug":"decryption-failed","errorCode":"DECRYPTION_FAILED","errorMessage":"`Token decryption failed: ${error instanceof Error ? error.message : 'Unknown error'}`","messagePattern":"`Token decryption failed: (.+?)`","errorType":"exception","errorClass":"AuthenticationError","httpStatus":null,"severity":"error","filePath":"packages/tm-core/src/modules/auth/utils/cli-crypto.ts","lineNumber":101,"sourceCode":"\t\t\t\tkey: privateKeyPem,\n\t\t\t\tpadding: crypto.constants.RSA_PKCS1_OAEP_PADDING,\n\t\t\t\toaepHash: 'sha256'\n\t\t\t},\n\t\t\tencryptedKey\n\t\t);\n\n\t\t// Decrypt tokens using AES-256-GCM\n\t\tconst decipher = crypto.createDecipheriv('aes-256-gcm', aesKey, iv);\n\t\tdecipher.setAuthTag(authTag);\n\n\t\tconst decrypted = Buffer.concat([\n\t\t\tdecipher.update(encryptedData),\n\t\t\tdecipher.final()\n\t\t]);\n\n\t\treturn JSON.parse(decrypted.toString('utf8')) as DecryptedTokens;\n\t} catch (error) {\n\t\tthrow new AuthenticationError(\n\t\t\t`Token decryption failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n\t\t\t'DECRYPTION_FAILED',\n\t\t\terror\n\t\t);\n\t}\n}\n","sourceCodeStart":83,"sourceCodeEnd":108,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/packages/tm-core/src/modules/auth/utils/cli-crypto.ts#L83-L108","documentation":"decryptTokens in cli-crypto wraps any failure while AES-decrypting the locally stored token blob into an AuthenticationError with code DECRYPTION_FAILED. It fires when decipher.update/final or the subsequent JSON.parse throws — i.e., the ciphertext, key, or stored format is invalid. The original error is preserved as the cause.","triggerScenarios":"Calling decryptTokens when the encrypted tokens file was written with a different key (machine/user change), the file is corrupted or truncated, or the decrypted plaintext is not valid JSON (JSON.parse throws).","commonSituations":"Restoring ~/.task-master config from a backup onto another machine (different crypto key); manually editing or partially copying the token file; library upgrade changing the encryption format; disk corruption.","solutions":["Delete the stored credential/token file and log in again (tm auth login) to regenerate and re-encrypt tokens","Restore the original encryption key/credentials or copy the tokens file from the original machine where it was encrypted","Verify the tokens file is not truncated or manually modified; re-download from backup taken with the same key","If this started after a version upgrade, re-authenticate so tokens are stored in the new format"],"exampleFix":"// before\nconst tokens = crypto.decryptTokens(encrypted); // throws DECRYPTION_FAILED\n// after\nlet tokens;\ntry {\n  tokens = crypto.decryptTokens(encrypted);\n} catch (e) {\n  if (e instanceof AuthenticationError && e.code === 'DECRYPTION_FAILED') {\n    await reAuthenticate(); // clears stale tokens and logs in again\n    return;\n  }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"import { existsSync } from 'fs';\nconst tokensPath = crypto.tokensFilePath;\nif (!existsSync(tokensPath)) await reAuthenticate();\nelse if (Buffer.byteLength(readFileSync(tokensPath)) === 0) await reAuthenticate(); // empty/corrupt","typeGuard":"function isDecryptionFailed(e: unknown): e is AuthenticationError {\n  return e instanceof AuthenticationError && e.code === 'DECRYPTION_FAILED';\n}","tryCatchPattern":"try {\n  tokens = decryptTokens(encrypted);\n} catch (e) {\n  if (isDecryptionFailed(e)) {\n    await clearStoredCredentials();\n    await reAuthenticate(); // tokens unreadable: log in again\n  } else { throw e; }\n}","preventionTips":["Never hand-edit or partially copy the encrypted token file","When migrating machines, re-authenticate instead of copying tokens (keys differ per machine)","Take config backups only from the same machine/user that encrypted them","Treat any DECRYPTION_FAILED as stale-credentials: clear and re-login rather than retrying decryption"],"tags":["crypto","auth","tokens","local-storage"],"backgroundTag":"token-decryption-failed","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}