Hmbown/CodeWhale · error · anyhow::Error

Automation run schema v

Error message

Automation run schema v{} is newer than supported v{}

What it means

read_run_file is the run-history counterpart of the automation schema guard: an AutomationRunRecord with schema_version above CURRENT_RUN_SCHEMA_VERSION is rejected rather than parsed, because an older binary cannot safely interpret a newer run file format.

Solutions

  1. Upgrade Codewhale to a build supporting the run schema version in the file.
  2. Discard or archive the too-new run files if staying on the old version is intentional.
  3. Keep separate data directories per app version to avoid mixing run histories across schema bumps.
Defensive patterns

Strategy: validation

Validate before calling

let run: AutomationRunRecord = serde_json::from_str(&raw)?;
if run.schema_version > CURRENT_RUN_SCHEMA_VERSION {
    // archive instead of loading
}

Type guard

fn supported_run(raw: &str) -> Option<AutomationRunRecord> {
    let run: AutomationRunRecord = serde_json::from_str(raw).ok()?;
    (run.schema_version <= CURRENT_RUN_SCHEMA_VERSION).then_some(run)
}

Try / catch

match read_run_file(&path) {
    Ok(r) => display(r),
    Err(e) if e.to_string().contains("newer than supported") => archive(&path),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Loading a persisted automation run file written by a newer Codewhale build into an older binary.

Common situations: Downgrading the app while keeping run history; copying run logs from a machine on a newer release; switching branches where the run schema was bumped.

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 Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/fd54bc5fa8fddb90. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/automation_manager.rs:2765

    let record: AutomationRecord = serde_json::from_str(&raw)
        .with_context(|| format!("Failed to parse automation {}", path.display()))?;
    if record.schema_version > CURRENT_AUTOMATION_SCHEMA_VERSION {
        bail!(
            "Automation schema v{} is newer than supported v{}",
            record.schema_version,
            CURRENT_AUTOMATION_SCHEMA_VERSION
        );
    }
    Ok(record)
}

fn read_run_file(path: &Path) -> Result<AutomationRunRecord> {
    let raw =
        fs::read_to_string(path).with_context(|| format!("Failed to read {}", path.display()))?;
    let run: AutomationRunRecord = serde_json::from_str(&raw)
        .with_context(|| format!("Failed to parse {}", path.display()))?;
    if run.schema_version > CURRENT_RUN_SCHEMA_VERSION {
        bail!(
            "Automation run schema v{} is newer than supported v{}",
            run.schema_version,
            CURRENT_RUN_SCHEMA_VERSION
        );
    }
    Ok(run)
}

fn ensure_safe_storage_id(kind: &str, value: &str) -> Result<()> {
    let mut components = Path::new(value).components();
    let Some(component) = components.next() else {
        bail!("{kind} must not be empty");
    };
    if components.next().is_some() || !matches!(component, std::path::Component::Normal(_)) {
        bail!("{kind} must be a single path component");
    }
    Ok(())
}

View on GitHub (pinned to 73e0f67d83)