Pre-existing (restore_one_file, src-tauri/src/commands/restore.rs ~:1762 and the bundle-member path ~:1399): any restored-plaintext BLAKE3 mismatch returns ErrorCode::CryptoDecryptFailed, whether or not the source is encrypted.
Surfaced by PR #269: the drill history panel is the first user-facing surface to render these codes verbatim, so a corrupted object on an UNENCRYPTED source shows as "crypto.decrypt_failed x2" - confusing for a user who knows they never enabled encryption.
Fix shape: split the code (e.g. restore.content_mismatch for plaintext sources, keep crypto.decrypt_failed for encrypted ones) or rename to something crypto-neutral, plus locale entries. Codes are persisted in drill reports, so keep from_label compatibility for old rows.
🤖 Generated with Claude Code
https://claude.ai/code/session_015jEKvjBzVjaWLq6o5zg2PV
Pre-existing (restore_one_file, src-tauri/src/commands/restore.rs ~:1762 and the bundle-member path ~:1399): any restored-plaintext BLAKE3 mismatch returns ErrorCode::CryptoDecryptFailed, whether or not the source is encrypted.
Surfaced by PR #269: the drill history panel is the first user-facing surface to render these codes verbatim, so a corrupted object on an UNENCRYPTED source shows as "crypto.decrypt_failed x2" - confusing for a user who knows they never enabled encryption.
Fix shape: split the code (e.g. restore.content_mismatch for plaintext sources, keep crypto.decrypt_failed for encrypted ones) or rename to something crypto-neutral, plus locale entries. Codes are persisted in drill reports, so keep from_label compatibility for old rows.
🤖 Generated with Claude Code
https://claude.ai/code/session_015jEKvjBzVjaWLq6o5zg2PV