atuinsh/atuin · info
writing to a Vec is infallible
Error message
writing to a Vec is infallible
What it means
`encode` builds a MessagePack representation of a PASETO v4 key inside a `Vec<u8>` and asserts each `rmp::encode::write_*` result with `.expect("writing to a Vec is infallible")`. rmp encode functions only fail on unsupported types/values; writing a small array header and single-byte uints into a `Vec` is provably infallible, so this is an invariant assertion.
Solutions
- No action needed; if rmp API changes, convert to returning a Result and propagate
Defensive patterns
Strategy: try-catch
Try / catch
// infallible for Vec targets; if rmp API changes: let _ = rmp::encode::write_array_len(&mut buf, u32::conv(key_bytes.len()));
Prevention
- Pin the rmp crate version
- Keep the pre-reserved capacity (3 + 2 * len) to guarantee no reallocation-related concerns
- Encode only values ≤ u8::MAX in the loop
When it happens
Trigger: Only reachable if the rmp encode functions start failing for these trivially valid arguments — effectively never; guarded by a breaking change of the rmp crate.
Common situations: Runs on every key save path (`try_write_path`, `overwrite_path`) when persisting the plaintext-encoded key.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- writing to a String cannot fail
- Atuin running with no parent!
- clone pty reader
- Could not build config
- Could not build default
AI-assisted analysis of atuinsh/atuin@900007c480 (2026-09-19).
Data as JSON: /api/errors/bf5b09cb10abad7c.
Report an issue: GitHub.
Appendix: source
Thrown at crates/atuin-common/src/encryption/paseto_v4.rs:173
p_self.wrap_pie(&p_wrapping)
}
/// Generate a new key with the XSalsa20Poly1305 algorithm.
#[must_use]
pub fn generate() -> Self {
<[u8; 32]>::from(XSalsa20Poly1305::generate_key(&mut aead::OsRng)).into()
}
/// Encode this key into a B64-encoded string, if possible.
#[must_use]
pub fn encode(&self) -> PlainTextEncodedKey {
let key_bytes = self.as_bytes();
// A msgpack array16 header (3 bytes) followed by each byte as at most a 2-byte uint.
let mut buf = Vec::with_capacity(3 + 2 * key_bytes.len());
// Writing to a `Vec` is infallible, so neither of these can actually error.
rmp::encode::write_array_len(&mut buf, u32::conv(key_bytes.len()))
.expect("writing to a Vec is infallible");
for b in key_bytes {
rmp::encode::write_uint(&mut buf, u64::from(*b))
.expect("writing to a Vec is infallible");
}
PlainTextEncodedKey(KEY_ENCODER.encode(buf))
}
pub fn decode(key: &str) -> Result<Self, KeyDecodingError> {
let buf = KEY_ENCODER.decode(key.trim_end())?;
// Legacy code used to naively encode the base64 string into the string. New code does this
// rmp dance.
match <[u8; 32]>::try_from(&*buf) {
Ok(key) => Ok(key.into()),
Err(_) => {
if buf.is_empty() {
return Err(KeyDecodingError::EmptyKey);View on GitHub (pinned to 900007c480)