nautechsystems/nautilus_trader · error

canonical diagnostics must be an array

Error message

canonical diagnostics must be an array

What it means

The 'diagnostics' section of a canonical result must be a JSON array (possibly empty). This error is thrown when the value is an object, string, null, or other non-array type. Enforced by validate_diagnostics during both document construction and parsing.

Source

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

            .get(key)
            .and_then(Value::as_array)
            .ok_or_else(|| anyhow::anyhow!("canonical component field '{key}' must be an array"))?;
        anyhow::ensure!(
            values.iter().all(Value::is_string),
            "canonical component field '{key}' must contain strings"
        );
    }
    anyhow::ensure!(
        object.get("trader_state").is_some_and(Value::is_string),
        "canonical trader state must be a string"
    );
    Ok(())
}

fn validate_diagnostics(value: &Value) -> anyhow::Result<()> {
    let diagnostics = value
        .as_array()
        .ok_or_else(|| anyhow::anyhow!("canonical diagnostics must be an array"))?;
    for diagnostic in diagnostics {
        let object = diagnostic
            .as_object()
            .ok_or_else(|| anyhow::anyhow!("canonical diagnostic must be an object"))?;
        validate_fields(object, &["code"], "canonical diagnostic")?;
        anyhow::ensure!(
            object.get("code").and_then(Value::as_str) == Some("funding-settlement-failed"),
            "unsupported canonical diagnostic code"
        );
    }
    Ok(())
}

fn validate_run(value: &Value) -> anyhow::Result<()> {
    let object = value
        .as_object()
        .ok_or_else(|| anyhow::anyhow!("canonical result run must be an object"))?;
    validate_fields(

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Change diagnostics to an array, using [] when there are no diagnostics
  2. Fix the producer/serializer so diagnostics are always collected into a list
  3. Regenerate the document with the library's canonical writer

Example fix

// before
"diagnostics": null
// after
"diagnostics": []
Defensive patterns

Strategy: validation

Validate before calling

fn diagnostics_is_array(doc: &serde_json::Value) -> bool {
    doc.get("diagnostics").map_or(false, |v| v.is_array())
}

Type guard

fn is_array(v: &serde_json::Value) -> bool { v.is_array() }

Try / catch

match CanonicalResult::from_slice(&bytes) {
    Ok(result) => /* use result */,
    Err(e) if e.to_string().contains("diagnostics must be an array") => /* convert diagnostics to an array */,
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: from_slice with "diagnostics": {} or "diagnostics": null; constructing a document whose diagnostics value is not a list.

Common situations: Hand-assembled JSON emitting diagnostics as an object keyed by code; a producer omitting the field to null when there are no diagnostics.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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