nautechsystems/nautilus_trader · error
canonical backtest result violates the version 1 encoding ru
Error message
canonical backtest result violates the version 1 encoding rules
What it means
`from_slice` validates that the parsed document is already in canonical form: it clones, canonicalizes, and requires the canonicalized value to equal the original document. If re-canonicalization changes anything (key order is fine since JSON objects compare by content, but e.g. number formatting/duplicates/extra or missing normalized fields differ), this error is thrown. The input must follow the version-1 encoding rules exactly.
Source
Thrown at crates/backtest/src/result.rs:193
}
impl CanonicalBacktestResult {
/// Decodes canonical result bytes and verifies their envelope, normalization, and exact
/// encoding.
///
/// Inner records retain their NautilusTrader model serialization and are compared as semantic
/// content. Producers must use the version 1 writer rather than construct records independently.
///
/// # Errors
///
/// Returns an error if the bytes are not a canonical version 1 result.
pub fn from_slice(bytes: &[u8]) -> anyhow::Result<Self> {
let document: Value = serde_json::from_slice(bytes)
.map_err(|e| anyhow::anyhow!("invalid canonical backtest result JSON: {e}"))?;
validate_document(&document)?;
let mut normalized = document.clone();
canonicalize_document(&mut normalized)?;
anyhow::ensure!(
normalized == document,
"canonical backtest result violates the version 1 encoding rules"
);
let canonical = serde_json::to_vec(&normalized)?;
anyhow::ensure!(
canonical == bytes,
"canonical backtest result bytes do not use the canonical encoding"
);
Ok(Self { document })
}
/// Returns the canonical compact UTF-8 JSON bytes without trailing data.
///
/// # Errors
///
/// Returns an error if the in-memory document cannot be serialized.
pub fn to_bytes(&self) -> anyhow::Result<Vec<u8>> {
Ok(serde_json::to_vec(&self.document)?)View on GitHub (pinned to 18893faf8b)
Solutions
- Regenerate the result bytes with the library's canonical serializer instead of hand-editing or re-serializing with another tool
- Round-trip: build a `BacktestResult` from state (`from_state`) and re-emit it canonically
- Compare your document against `canonicalize_document` output to find the diverging field and fix its encoding
- Ensure the result was produced by the same library version that defines CANONICAL_SCHEMA v1 rules
Example fix
// before let bytes = serde_json::to_vec(&value)?; // non-canonical number formatting BacktestResult::from_slice(&bytes)?; // after let result = BacktestResult::from_state(state)?; // canonical by construction let bytes = result.to_bytes()?; // then from_slice succeeds
Defensive patterns
Strategy: validation
Validate before calling
// Verify document survives canonicalization unchanged let mut normalized = document.clone(); canonicalize_document(&mut normalized)?; assert_eq!(normalized, document, "document is not canonically encoded");
Try / catch
match BacktestResult::from_slice(&bytes) {
Err(e) if e.to_string().contains("violates the version 1 encoding rules") => {
eprintln!("non-canonical content, regenerate via canonical writer");
}
Err(e) => return Err(e),
Ok(r) => r,
} Prevention
- Only load bytes produced by the library's canonical writer
- Never hand-edit result JSON; edit inputs and re-run the backtest
- Use from_state when you hold in-memory data instead of reconstructing JSON
When it happens
Trigger: Feeding a semantically valid but non-canonical result document: fields added/removed/reordered in a way canonicalization would alter, numbers serialized differently than the canonical encoder would (e.g. `1.0` vs `1`, exponent forms), or a hand-edited result file.
Common situations: Manually editing a saved backtest result; re-serializing a result with a different JSON library that formats numbers differently; results produced by an older or newer version of the canonicalizer.
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
- canonical backtest result bytes do not use the canonical enc
- canonical backtest result must be a JSON object
- canonical result field '{key}' must be an array
- canonical result summary must be an object
- canonical run configuration ID must be a string or null
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/4d33acfcca4a5be1.
Report an issue: GitHub.