atuinsh/atuin · error

too many entries in v0 kv record

Error message

too many entries in v0 kv record

What it means

A v0 kv record is encoded as a msgpack array of exactly 3 fields (namespace, key, value). The kv store deserializer reads the array length and rejects any record that does not have exactly 3 entries, treating it as malformed. This enforces the v0 on-disk/wire schema for the synced key-value store.

Source

Thrown at crates/atuin-kv/src/store/record.rs:46

            encode::write_str(&mut output, value)?;
        }

        Ok(DecryptedData(output))
    }

    pub fn deserialize(data: &DecryptedData, version: &RecordVersion) -> Result<Self> {
        use rmp::decode;

        fn error_report<E: std::fmt::Debug>(err: E) -> eyre::Report {
            eyre!("{err:?}")
        }

        match version {
            RecordVersion::V0 => {
                let mut bytes = decode::Bytes::new(&data.0);

                let nfields = decode::read_array_len(&mut bytes).map_err(error_report)?;
                ensure!(nfields == 3, "too many entries in v0 kv record");

                let bytes = bytes.remaining_slice();

                let (namespace, bytes) =
                    decode::read_str_from_slice(bytes).map_err(error_report)?;
                let (key, bytes) = decode::read_str_from_slice(bytes).map_err(error_report)?;
                let (value, bytes) = decode::read_str_from_slice(bytes).map_err(error_report)?;

                if !bytes.is_empty() {
                    bail!("trailing bytes in encoded kvrecord. malformed");
                }

                Ok(Self {
                    namespace: namespace.to_owned(),
                    key: key.to_owned(),
                    value: Some(value.to_owned()),
                })
            }

View on GitHub (pinned to c0c717ab04)

Solutions

  1. Upgrade all atuin clients sharing the kv store to the same version
  2. Delete the bad kv record and re-set the key with `atuin kv set`
  3. Re-sync the kv store from a known-good machine
  4. Inspect the record store DB row if the problem is isolated
Defensive patterns

Strategy: validation

Validate before calling

let n = rmp::decode::read_array_len(&mut bytes)?;
if n != 3 { return Err("malformed v0 kv record".into()); }

Try / catch

match KvRecord::deserialize(RecordVersion::V0, &data) {
    Ok(rec) => apply(rec),
    Err(e) => log::warn!("skipping malformed kv record: {e}"),
}

Prevention

When it happens

Trigger: Deserializing a RecordVersion::V0 kv record whose msgpack payload decodes to an array length other than 3.

Common situations: Records synced from a newer client (different schema) into an older reader; corrupted record payloads; third-party writes to the kv record store.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of atuinsh/atuin@c0c717ab04 (2026-09-12). Data as JSON: /api/errors/3e981dd38b3a3511. Report an issue: GitHub.