nautechsystems/nautilus_trader · error

unsupported canonical backtest result schema

Error message

unsupported canonical backtest result schema

What it means

After confirming the document is an object, `validate_document` requires `object["schema"]` to equal the supported canonical schema string (version 1). Any other value — different version string, missing field, or non-string — produces this error. It guards against loading results written by incompatible schema versions.

Source

Thrown at crates/backtest/src/result.rs:308

                "total_positions": state.total_positions.to_string(),
                "trader_id": state.trader_id,
            },
            "schema": CANONICAL_SCHEMA,
            "statistics": canonical_statistics(state.statistics),
            "summary": state.summary,
        });

        canonicalize_document(&mut document)?;
        validate_document(&document)?;
        Ok(Self { document })
    }
}

fn validate_document(document: &Value) -> anyhow::Result<()> {
    let object = document
        .as_object()
        .ok_or_else(|| anyhow::anyhow!("canonical backtest result must be a JSON object"))?;
    anyhow::ensure!(
        object.get("schema").and_then(Value::as_str) == Some(CANONICAL_SCHEMA),
        "unsupported canonical backtest result schema"
    );
    let fields = [
        "accounts",
        "components",
        "diagnostics",
        "fills",
        "orders",
        "portfolio_snapshots",
        "position_snapshots",
        "positions",
        "run",
        "schema",
        "statistics",
        "summary",
    ];
    validate_fields(object, &fields, "canonical result")?;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Set/regenerate the document so `schema` equals the supported canonical value (version 1 string used by the library)
  2. Migrate old-format results to the current schema before loading, or re-run the backtest to produce current-format results
  3. Check that the file is the canonical result document, not an intermediate or legacy export
  4. Verify no post-processing step rewrote or dropped the `schema` field

Example fix

// before
{"schema": "nautilus.backtest.v0", ...}
// after
{"schema": "nautilus.backtest.v1", ...} // exact CANONICAL_SCHEMA string supported by this version
Defensive patterns

Strategy: validation

Validate before calling

doc = json.load(open(path))
assert doc.get("schema") == EXPECTED_SCHEMA, f"unsupported schema: {doc.get('schema')}"

Type guard

fn has_supported_schema(doc: &serde_json::Value) -> bool {
    doc.get("schema").and_then(|v| v.as_str()) == Some(CANONICAL_SCHEMA)
}

Try / catch

match BacktestResult::from_slice(&bytes) {
    Err(e) if e.to_string().contains("unsupported canonical backtest result schema") => {
        eprintln!("schema version mismatch — migrate or re-run: {e:#}");
    }
    Err(e) => return Err(e),
    Ok(r) => r,
}

Prevention

When it happens

Trigger: Loading a backtest result whose `schema` field is absent, misspelled, or set to a different version (e.g. produced by an older/newer format) via `from_slice` or `from_state`.

Common situations: Upgrading or downgrading the library so saved results use a schema version no longer accepted; hand-editing the schema field; a custom producer forgetting to set `schema`.

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 nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/75bcb68bf7271f5b. Report an issue: GitHub.