{"record":{"id":"a1402161420cf0eb","repo":"slopus/happy","slug":"failed-to-decrypt-data-key-for-happy-session-ses","errorCode":null,"errorMessage":"Failed to decrypt data key for Happy session ${session.id}","messagePattern":"Failed to decrypt data key for Happy session (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/happy-cli/src/resume/resolveHappySession.ts","lineNumber":104,"sourceCode":"}\n\nfunction readAgentCredentials() {\n    const credentialPath = getLocalHappyAgentCredentialPath();\n    const credentials = readLocalHappyAgentCredentials();\n    if (!credentials) {\n        throw new Error(\n            `Cannot resume historical Happy sessions through legacy account credentials because ${credentialPath} is missing.`,\n        );\n    }\n    return credentials;\n}\n\nfunction resolveSessionEncryption(session: RawSession, credentials: LocalHappyAgentCredentials): RecordEncryption {\n    if (session.dataEncryptionKey) {\n        const encrypted = decodeBase64(session.dataEncryptionKey);\n        const sessionKey = decryptBoxBundle(encrypted.slice(1), credentials.contentKeyPair.secretKey);\n        if (!sessionKey) {\n            throw new Error(`Failed to decrypt data key for Happy session ${session.id}`);\n        }\n        return {\n            key: sessionKey,\n            variant: 'dataKey',\n        };\n    }\n\n    return {\n        key: credentials.secret,\n        variant: 'legacy',\n    };\n}\n\nfunction decryptSessionMetadata(session: RawSession, credentials: LocalHappyAgentCredentials): Metadata {\n    const encryption = resolveSessionEncryption(session, credentials);\n    const encryptedMetadata = decodeBase64(session.metadata);\n    const metadata = encryption.variant === 'dataKey'\n        ? decryptWithDataKey(encryptedMetadata, encryption.key)","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/slopus/happy/blob/b824cd0a4681d41af631a8e422a813873e4455b0/packages/happy-cli/src/resume/resolveHappySession.ts#L86-L122","documentation":"resolveSessionEncryption decrypts the session's base64 dataEncryptionKey using the account's content key pair (secretKey) via a NaCl box bundle. If decryptBoxBundle returns null — decryption failed because this account's secret key cannot open the bundle — it throws this error naming the session. It means the session's data key is not recoverable with the current credentials.","triggerScenarios":"Calling resolveSessionEncryption for a session whose dataEncryptionKey was encrypted to a different account's public key; corrupted or truncated key bundle; credentials from a different happy account than the session owner; base64 payload malformed.","commonSituations":"Logged in with the wrong account; team/shared sessions where the key was rotated; machine restored from backup with stale credentials; server-side data corrupted or partially migrated.","solutions":["Verify you are authenticated as the account that created/owns the session; re-login with the correct account.","Confirm the credentials content key pair matches the one used at session creation (don't mix accounts across machines).","If the key was rotated or the session was created under an old account, resume from the original machine or export/import the correct key pair.","If the bundle is corrupt, start a new session — the data key is unrecoverable."],"exampleFix":"// before\n$ happy auth --account work    # wrong account\n$ happy resume <session-id>    // Failed to decrypt data key\n// after\n$ happy auth --account personal  # owning account\n$ happy resume <session-id>","handlingStrategy":"try-catch","validationCode":"// Verify identity before resuming:\nconst creds = readLocalHappyAgentCredentials();\nif (creds.accountId !== expectedOwnerAccountId) {\n  console.error('Logged in with the wrong account for this session');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await resolveHappySession(id);\n} catch (err) {\n  if ((err as Error).message.startsWith('Failed to decrypt data key')) {\n    // surface 'wrong account / unrecoverable key' to the user; prompt re-login as owning account\n  } else throw err;\n}","preventionTips":["Resume sessions only under the account that created them.","Avoid mixing account credentials across machines; re-auth explicitly when switching accounts.","Back up/export key pairs if sessions must survive machine migration."],"tags":["encryption","crypto","credentials","session-resume"],"backgroundTag":"decryption-failed","analyzedSha":"b824cd0a4681d41af631a8e422a813873e4455b0","analyzedAt":"2026-08-31T23:12:36.205Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}