atuinsh/atuin · error

too many entries in v0 shell alias delete record

Error message

too many entries in v0 shell alias delete record

What it means

The v0 shell alias delete record must be a MsgPack array of exactly 1 entry (the key). When the discriminator byte is 1 (delete), the deserializer enforces nfields == 1 and rejects anything else. This guards against malformed or newer-schema payloads.

Solutions

  1. Re-issue the delete operation through the current CLI rather than replaying the old record.
  2. Fix the encoder to write exactly one entry (key) for delete records.
  3. Sync-check all peers' Atuin versions and upgrade.

Example fix

// before: encode::to_bytes(&(key, extra))
// after:  encode::to_bytes(&(key,))
Defensive patterns

Strategy: validation

Validate before calling

let value: rmpv::Value = rmpv::decode::read_value(&mut cursor)?;
// delete variant: discriminator 1 requires exactly 1 field
assert_eq!(value.as_array().map(|a| a.len()), Some(1));

Type guard

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

Try / catch

match ShellAlias::deserialize(&bytes) {
    Ok(alias) => handle(alias),
    Err(e) if e.to_string().contains("too many entries") => {
        log::warn("dropping malformed alias delete record");
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Deserializing a v0 alias delete record whose array length is not 1 — e.g. an encoder that wrote key plus extra fields, or a payload where the delete variant was mis-encoded.

Common situations: Records produced by a newer Atuin version synced to an older client, hand-written record encoders, or corrupted sync data.

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/f23ebc67afbae467. Report an issue: GitHub.

Appendix: source

Thrown at crates/atuin-dotfiles/src/store.rs:92

                        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 shell alias record. malformed");
                        }

                        Ok(Self::Create(Alias {
                            name: key.to_owned(),
                            value: value.to_owned(),
                        }))
                    }

                    // delete
                    1 => {
                        let nfields = decode::read_array_len(&mut bytes).map_err(error_report)?;
                        ensure!(nfields == 1, "too many entries in v0 shell alias delete record");

                        let bytes = bytes.remaining_slice();

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

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

                        Ok(Self::Delete(key.to_owned()))
                    }

                    n => {
                        bail!("unknown AliasRecord type {n}");
                    }
                }
            }

View on GitHub (pinned to 900007c480)