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

  1. Ensure every required field is present as an array — use `[]` for empty, never `null` or `{}`
  2. Regenerate the document with the canonical writer so all fields are emitted
  3. Fix any post-processing that deletes or replaces these fields
  4. 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

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/30add6dfc88f2c42. Report an issue: GitHub.