{"record":{"id":"598817b97083a146","repo":"atuinsh/atuin","slug":"trailing-bytes-in-encoded-shell-alias-record-malf","errorCode":null,"errorMessage":"trailing bytes in encoded shell alias record. malformed","messagePattern":"trailing bytes in encoded shell alias record\\. malformed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/atuin-dotfiles/src/store.rs","lineNumber":80,"sourceCode":"                let mut bytes = decode::Bytes::new(&data.0);\n\n                let record_type = decode::read_u8(&mut bytes).map_err(error_report)?;\n\n                match record_type {\n                    // create\n                    0 => {\n                        let nfields = decode::read_array_len(&mut bytes).map_err(error_report)?;\n                        ensure!(nfields == 2, \"too many entries in v0 shell alias create record\");\n\n                        let bytes = bytes.remaining_slice();\n\n                        let (key, bytes) =\n                            decode::read_str_from_slice(bytes).map_err(error_report)?;\n                        let (value, bytes) =\n                            decode::read_str_from_slice(bytes).map_err(error_report)?;\n\n                        if !bytes.is_empty() {\n                            bail!(\"trailing bytes in encoded shell alias record. malformed\");\n                        }\n\n                        Ok(Self::Create(Alias {\n                            name: key.to_owned(),\n                            value: value.to_owned(),\n                        }))\n                    }\n\n                    // delete\n                    1 => {\n                        let nfields = decode::read_array_len(&mut bytes).map_err(error_report)?;\n                        ensure!(nfields == 1, \"too many entries in v0 shell alias delete record\");\n\n                        let bytes = bytes.remaining_slice();\n\n                        let (key, bytes) =\n                            decode::read_str_from_slice(bytes).map_err(error_report)?;\n","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/atuinsh/atuin/blob/c0c717ab04c881764bcad4b3d169a507e2432643/crates/atuin-dotfiles/src/store.rs#L62-L98","documentation":"While decoding an Alias record tagged Create (tag 0), extra bytes remained after reading the key/value string pair. Alias::Create payloads must contain exactly two strings, so leftovers indicate a malformed record.","triggerScenarios":"Deserializing an alias record with trailing bytes — corrupted record store blob, or a record written by an incompatible dotfiles record format version.","commonSituations":"Damaged local record database; syncing alias records from mismatched atuin versions.","solutions":["Re-sync the dotfiles record store (delete local record DB and re-download from the Hub)","Upgrade atuin on all synced machines to the same version","Restore the record store from a known-good backup"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"fn is_wellformed_alias_create(payload: &[u8]) -> bool {\n    let (key, rest) = match decode::read_str_from_slice(payload) { Ok(v) => v, Err(_) => return false };\n    let (_, rest) = match decode::read_str_from_slice(rest) { Ok(v) => v, Err(_) => return false };\n    rest.is_empty()\n}","tryCatchPattern":"match Alias::deserialize(bytes) {\n    Ok(a) => apply(a),\n    Err(e) if e.to_string().contains(\"trailing bytes\") => {\n        log::warn!(\"corrupt alias record skipped: {e}\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Keep atuin versions aligned across synced devices","Avoid killing atuin mid-sync to prevent partial record writes"],"tags":["serialization","corruption","dotfiles"],"backgroundTag":"unexpected-response-shape","analyzedSha":"c0c717ab04c881764bcad4b3d169a507e2432643","analyzedAt":"2026-09-12T07:40:01.341Z","contentChangedAt":"2026-09-12T07:40:01.341Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}