atuinsh/atuin · error
trailing bytes decoding HistoryRecord::Delete - malformed?…
Error message
trailing bytes decoding HistoryRecord::Delete - malformed? got {bytes:?} What it means
`HistoryRecord::deserialize` (atuin-client/src/history/store.rs) decodes record-type 1 (Delete) as a single string id read via `read_str_from_slice`. If the remaining buffer still has bytes after reading the id, the record framing is malformed, so it bails. This is a corruption/protocol-safety check on binary record payloads received from sync.
Solutions
- Identify the offending record and delete it from the record store so sync can re-fetch a clean copy
- Back up and inspect the record DB (`~/.local/share/atuin/records.db` or similar) for corruption
- Update atuin on all syncing machines to matching versions to eliminate format skew
- As a last resort, reset the record store and re-sync from the server
Defensive patterns
Strategy: try-catch
Try / catch
match record_decode_result {
Err(e) if e.to_string().contains("trailing bytes decoding HistoryRecord::Delete") => {
// quarantine the record id and re-sync it
}
other => other?,
} Prevention
- Keep atuin versions identical across all sync devices
- Never manually edit the record store database
- Back up ~/.local/share/atuin before risky operations
- Let interrupted syncs resume rather than force-killing them
When it happens
Trigger: Deserializing a history record whose type byte is 1 but whose payload contains extra bytes after the string id — e.g. truncated-then-resumed sync streams, a record written by an incompatible record version, or corrupted local record store data.
Common situations: Syncing against a server/peer producing records in a newer format; interrupted sync leaving partial data; manually edited or corrupted `~/.local/share/atuin` record database.
Understand the failure class
Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- trailing bytes in encoded shell alias record. malformed
- invalid id UUID format in sqlite DB
- unknown HistoryRecord type
- could not sync records due to version mismatch
- failed to parse uuid for local store status
AI-assisted analysis of atuinsh/atuin@900007c480 (2026-09-19).
Data as JSON: /api/errors/1813dfdca0291792.
Report an issue: GitHub.
Appendix: source
Thrown at crates/atuin-client/src/history/store.rs:112
// 0 -> HistoryRecord::Create
0 => {
// not super useful to us atm, but perhaps in the future
// written by write_bin above
let _ = decode::read_bin_len(&mut bytes).map_err(error_report)?;
let record =
History::deserialize(bytes.remaining_slice(), version).map_err(error_report)?;
Ok(Self::Create(record))
}
// 1 -> HistoryRecord::Delete
1 => {
let bytes = bytes.remaining_slice();
let (id, bytes) = decode::read_str_from_slice(bytes).map_err(error_report)?;
if !bytes.is_empty() {
bail!(
"trailing bytes decoding HistoryRecord::Delete - malformed? got {bytes:?}"
);
}
Ok(Self::Delete(id.parse()?))
}
n => {
bail!("unknown HistoryRecord type {n}");
}
}
}
}
/// How many entries `incremental_build` holds in memory, and the most it puts into a single
/// `save_bulk`/`delete_rows` transaction.
const BUILD_BATCH_SIZE: NonZeroUsize = NonZeroUsize::new(5000).unwrap();
View on GitHub (pinned to 900007c480)