Hmbown/CodeWhale · error · std::io::Error

unsupported legacy spillover ownership schema

Error message

unsupported legacy spillover ownership schema

What it means

InvalidData returned by read_legacy_spillover_ownership when the sidecar's schema_version does not equal LEGACY_SPILLOVER_OWNER_SCHEMA_VERSION. The sidecar JSON parsed fine but was written by a different (older or newer) Codewhale version whose ownership schema is not the one this build understands, so the reader refuses instead of misinterpreting fields.

Source

Thrown at crates/tui/src/tools/truncate.rs:174

}

pub(crate) fn read_legacy_spillover_ownership(
    payload_path: &Path,
) -> io::Result<LegacySpilloverOwnership> {
    let sidecar = legacy_spillover_ownership_path(payload_path);
    if std::fs::symlink_metadata(&sidecar)?
        .file_type()
        .is_symlink()
    {
        return Err(io::Error::new(
            io::ErrorKind::PermissionDenied,
            "legacy spillover ownership sidecar must not be a symlink",
        ));
    }
    let ownership = serde_json::from_slice::<LegacySpilloverOwnership>(&std::fs::read(sidecar)?)
        .map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))?;
    if ownership.schema_version != LEGACY_SPILLOVER_OWNER_SCHEMA_VERSION {
        return Err(io::Error::new(
            io::ErrorKind::InvalidData,
            "unsupported legacy spillover ownership schema",
        ));
    }
    Ok(ownership)
}

/// Resolve the spillover-file path for a SHA256 content hash. Separate
/// namespace (`sha_<hex>.txt`) from the tool-call-id files so legacy
/// SHA-addressed evidence can be recognized without colliding with
/// tool-call references. Retrieval still requires matching ownership
/// metadata. `sha` must be the raw 64-char lowercase hex digest —
/// case-insensitive matching is done by the caller.
#[must_use]
pub fn sha_spillover_path(sha: &str) -> Option<PathBuf> {
    let sha = sha.trim().to_ascii_lowercase();
    if !is_valid_sha256(&sha) {
        return None;

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Discard the stale sidecar/payload: delete the old spillover file(s) so ownership is re-established on the next write
  2. Re-publish the affected output with the current version instead of reusing old spillover artifacts
  3. Keep one Codewhale version per home directory; avoid mixed-version installs sharing state

Example fix

# before
# sidecar written by older release: {"schema_version": 1, ...}, current build expects 2
# read -> InvalidData: unsupported legacy spillover ownership schema

# after
$ rm ~/.codewhale/spillover/sha_<hex>.ownership   # stale metadata only
# re-run the tool output write; the current version rewrites the sidecar
Defensive patterns

Strategy: fallback

Validate before calling

let raw = std::fs::read(&sidecar)?;
let probe: serde_json::Value = serde_json::from_slice(&raw)?;
if probe.get("schema_version") != Some(&serde_json::json!(LEGACY_SPILLOVER_OWNER_SCHEMA_VERSION)) {
    // stale artifact from another version: drop it and re-publish instead of reading
}

Type guard

fn is_schema_mismatch(e: &std::io::Error) -> bool {
    e.kind() == std::io::ErrorKind::InvalidData
        && e.to_string().contains("unsupported legacy spillover ownership schema")
}

Prevention

When it happens

Trigger: Reading a legacy spillover ownership sidecar written by a previous release after an upgrade (or by a newer release after a downgrade): the JSON parses, but schema_version no longer matches the compiled constant.

Common situations: Version rollforward/rollback across releases that bumped the ownership schema; long-lived machines with stale spillover directories; parallel installs of two Codewhale versions sharing one home directory.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/8bcf9e745682d718. Report an issue: GitHub.