nautechsystems/nautilus_trader · error
canonical result field '{key}' must be an array
Error message
canonical result field '{key}' must be an array What it means
`validate_document` requires each canonical list field (`accounts`, `components`, `diagnostics` items, `fills`, `orders`, `portfolio_snapshots`, `position_snapshots`, `positions`) to be present and to be a JSON array. If any of these fields is missing, null, an object, or another non-array type, this error names the offending key.
Source
Thrown at crates/backtest/src/result.rs:337
"position_snapshots",
"positions",
"run",
"schema",
"statistics",
"summary",
];
validate_fields(object, &fields, "canonical result")?;
for key in [
"accounts",
"diagnostics",
"fills",
"orders",
"portfolio_snapshots",
"position_snapshots",
"positions",
] {
anyhow::ensure!(
object.get(key).is_some_and(Value::is_array),
"canonical result field '{key}' must be an array"
);
}
validate_components(object.get("components").expect("validated field"))?;
validate_diagnostics(object.get("diagnostics").expect("validated field"))?;
validate_run(object.get("run").expect("validated field"))?;
validate_statistics(object.get("statistics").expect("validated field"))?;
let summary = object
.get("summary")
.and_then(Value::as_object)
.ok_or_else(|| anyhow::anyhow!("canonical result summary must be an object"))?;
anyhow::ensure!(
summary.values().all(Value::is_string),
"canonical result summary values must be strings"
);
Ok(())
}View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure every required field is present as an array — use `[]` for empty, never `null` or `{}`
- Regenerate the document with the canonical writer so all fields are emitted
- Fix any post-processing that deletes or replaces these fields
- Check the field name in the error message to find the exact key to repair
Example fix
// before
{"schema":"...","orders":null,"fills":[]}
// after
{"schema":"...","orders":[],"fills":[]} Defensive patterns
Strategy: type-guard
Validate before calling
REQUIRED = ["accounts","components","fills","orders","portfolio_snapshots","position_snapshots","positions"] assert all(isinstance(doc.get(k), list) for k in REQUIRED), "missing/non-array result field"
Type guard
fn has_required_arrays(doc: &serde_json::Value) -> bool {
["accounts","components","fills","orders","portfolio_snapshots","position_snapshots","positions"]
.iter().all(|k| doc.get(*k).is_some_and(serde_json::Value::is_array))
} Try / catch
match BacktestResult::from_slice(&bytes) {
Err(e) if e.to_string().contains("must be an array") => {
eprintln!("required array field missing or wrong type: {e:#}");
}
Err(e) => return Err(e),
Ok(r) => r,
} Prevention
- Emit `[]` for empty collections, never null
- Disable 'drop empty fields' options in post-processing/compression tools
- Run validate_document-style checks on any custom writer's output before saving
When it happens
Trigger: Loading a result document where one of the required array fields was dropped by a partial export, set to `null` (e.g. by a 'no data' serializer), or replaced by an object/mapping.
Common situations: Custom result writers emitting `{"orders": null}` instead of `[]`; post-processing scripts that delete empty fields to shrink files; merging results and losing a field.
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 must be a JSON object
- canonical result summary must be an object
- canonical run configuration ID must be a string or null
- canonical trader ID must be a string
- canonical result statistics must be an object
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/30add6dfc88f2c42.
Report an issue: GitHub.