Skip to content

kv::get_borsh returns opaque decode error for missing keys instead of a distinguishable not-found error #28

Description

@joshuajbouw

Summary

kv::get_borsh has no guard for the "key not found" case. When a key is absent, kv_get returns None, get_bytes returns an empty Vec<u8>, and borsh::from_slice(&[]) returns a BorshDecodeError. Callers cannot distinguish "key was never written" from "key exists but is corrupted data."

Context

Found as an out-of-scope observation while reviewing PR for feat/wasmtime-component-model. Pre-dates this branch.

The analogous get_json function also has this behavior (empty bytes -> JsonError), but the macro-generated state loading treats JsonError as "use Default" — which works by accident. get_borsh has no such fallback.

Impact

Capsule code using Borsh serialization for KV state cannot reliably detect first-run (key absent) vs data corruption. First-run initialization logic may fail with a misleading error.

Suggested Fix

pub fn get_borsh<T: BorshDeserialize>(key: impl AsRef<[u8]>) -> Result<T, SysError> {
    let bytes = get_bytes(key)?;
    if bytes.is_empty() {
        return Err(SysError::ApiError("key not found".into()));
    }
    let parsed = borsh::from_slice(&bytes)?;
    Ok(parsed)
}

Or expose a get_borsh_optional that returns Result<Option<T>, SysError>.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions