eyaltoledano/claude-task-master · error · AuthenticationError
DECRYPTION_FAILED
DECRYPTION_FAILED
Error message
`Token decryption failed: ${error instanceof Error ? error.message : 'Unknown error'}` What it means
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.
Source
Thrown at packages/tm-core/src/modules/auth/utils/cli-crypto.ts:101
key: privateKeyPem,
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
oaepHash: 'sha256'
},
encryptedKey
);
// Decrypt tokens using AES-256-GCM
const decipher = crypto.createDecipheriv('aes-256-gcm', aesKey, iv);
decipher.setAuthTag(authTag);
const decrypted = Buffer.concat([
decipher.update(encryptedData),
decipher.final()
]);
return JSON.parse(decrypted.toString('utf8')) as DecryptedTokens;
} catch (error) {
throw new AuthenticationError(
`Token decryption failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
'DECRYPTION_FAILED',
error
);
}
}
View on GitHub (pinned to c0c98d367c)
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
Example fix
// before
const tokens = crypto.decryptTokens(encrypted); // throws DECRYPTION_FAILED
// after
let tokens;
try {
tokens = crypto.decryptTokens(encrypted);
} catch (e) {
if (e instanceof AuthenticationError && e.code === 'DECRYPTION_FAILED') {
await reAuthenticate(); // clears stale tokens and logs in again
return;
}
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
import { existsSync } from 'fs';
const tokensPath = crypto.tokensFilePath;
if (!existsSync(tokensPath)) await reAuthenticate();
else if (Buffer.byteLength(readFileSync(tokensPath)) === 0) await reAuthenticate(); // empty/corrupt Type guard
function isDecryptionFailed(e: unknown): e is AuthenticationError {
return e instanceof AuthenticationError && e.code === 'DECRYPTION_FAILED';
} Try / catch
try {
tokens = decryptTokens(encrypted);
} catch (e) {
if (isDecryptionFailed(e)) {
await clearStoredCredentials();
await reAuthenticate(); // tokens unreadable: log in again
} else { throw e; }
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Related errors
AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29).
Data as JSON: /api/errors/1fb3c244cb1f6960.
Report an issue: GitHub.