atuinsh/atuin · error

unknown script record version

Error message

unknown script record version {other:?}

What it means

The script record decoder reads a version byte and dispatches on a record-type byte inside it. Unknown versions bail with this error before any type parsing happens. It prevents decoding payloads written in an unrecognized format version.

Solutions

  1. Upgrade atuin (atuin-scripts) to the latest version
  2. Skip records with unknown versions during sync
  3. Delete the offending record from the record store
Defensive patterns

Strategy: try-catch

Validate before calling

// Check the script record version byte before decoding
// fn is_supported_script_version(payload: &[u8]) -> bool {
//     payload.first() == Some(&SCRIPT_KNOWN_VERSION)
// }

Type guard

fn is_supported_script_version(payload: &[u8]) -> bool {
    payload.first() == Some(&SCRIPT_KNOWN_VERSION)
}

Try / catch

match ScriptRecord::deserialize(&mut bytes) {
    Ok(rec) => apply(rec),
    Err(e) if e.to_string().contains("unknown script record version") => {
        log::warn!("script record version unsupported; upgrade atuin");
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Deserializing a script record payload whose version byte is not supported by this build — e.g. records created by a newer atuin-scripts release.

Common situations: Older atuin client syncing script records from a newer client; mixing versions across machines.

Related errors


AI-assisted analysis of atuinsh/atuin@900007c480 (2026-09-19). Data as JSON: /api/errors/dc9709d80ee3c687. Report an issue: GitHub.

Appendix: source

Thrown at crates/atuin-scripts/src/store/record.rs:87

                    // delete
                    1 => {
                        let bytes = bytes.remaining_slice();
                        let (id, _) = decode::read_str_from_slice(bytes).map_err(error_report)?;
                        Ok(Self::Delete(Uuid::parse_str(id)?))
                    }

                    // update
                    2 => {
                        // written by encode::write_bin above
                        let _ = decode::read_bin_len(&mut bytes).map_err(error_report)?;
                        let script = Script::deserialize(bytes.remaining_slice())?;
                        Ok(Self::Update(script))
                    }

                    _ => Err(eyre!("unknown script record type {record_type}")),
                }
            }
            other => bail!("unknown script record version {other:?}"),
        }
    }
}

#[cfg(test)]
mod tests {
    use rstest::rstest;

    use super::*;

    #[test]
    fn test_serialize_create() {
        let script = Script::builder()
            .id(uuid::Uuid::parse_str("0195c825a35f7982bdb016168881cbc6").unwrap())
            .name("test".to_string())
            .description("test".to_string())
            .shebang("test".to_string())
            .tags(vec!["test".to_string()])

View on GitHub (pinned to 900007c480)