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 must be a MsgPack array of exactly 3 entries: namespace, key, and value. The KV record deserializer checks the array length first and rejects any deviation, so payloads with extra or missing fields cannot be silently misread.

Solutions

  1. Re-write the KV entry with your current client: delete the key and set it again via `atuin kv`.
  2. Fix any custom writer to emit exactly (namespace, key, value) for V0 records, or encode as V1 instead.
  3. Align schema versions across sync peers.

Example fix

// before: encode::to_bytes(&(namespace, key, value, metadata))
// after:  encode::to_bytes(&(namespace, key, value))
Defensive patterns

Strategy: validation

Validate before calling

let value: rmpv::Value = rmpv::decode::read_value(&mut cursor)?;
// v0 kv record requires exactly 3 fields
assert_eq!(value.as_array().map(|a| a.len()), Some(3));

Type guard

fn is_well_formed_v0_kv(payload: &[u8]) -> bool {
    rmpv::decode::read_value(&mut std::io::Cursor::new(payload))
        .ok()
        .and_then(|v| v.as_array().map(|a| a.len() == 3))
        .unwrap_or(false)
}

Try / catch

match KvRecord::deserialize(&data) {
    Ok(rec) => apply(rec),
    Err(e) if e.to_string().contains("too many entries") => {
        log::warn("malformed v0 kv record skipped: {e}");
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Deserializing a record tagged V0 whose array length != 3 — e.g. encoded by a newer KV schema, written with extra metadata fields, or corrupted in storage.

Common situations: KV records synced from clients on different Atuin/KV schema versions, third-party writers to the record store, or truncated/corrupted payloads.

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@900007c480 (2026-09-19). Data as JSON: /api/errors/3e981dd38b3a3511. Report an issue: GitHub.

Appendix: 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 900007c480)