{"record":{"id":"70430d6d6ca73171","repo":"nautechsystems/nautilus_trader","slug":"canonical-trader-id-must-be-a-string","errorCode":null,"errorMessage":"canonical trader ID must be a string","messagePattern":"canonical trader ID must be a string","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/backtest/src/result.rs","lineNumber":458,"sourceCode":"    for key in [\n        \"iterations\",\n        \"total_events\",\n        \"total_orders\",\n        \"total_positions\",\n    ] {\n        validate_unsigned_decimal(object.get(key).expect(\"validated field\"), key, false)?;\n    }\n\n    for key in [\"backtest_start_ns\", \"backtest_end_ns\"] {\n        validate_unsigned_decimal(object.get(key).expect(\"validated field\"), key, true)?;\n    }\n    anyhow::ensure!(\n        object\n            .get(\"run_config_id\")\n            .is_some_and(|value| value.is_null() || value.is_string()),\n        \"canonical run configuration ID must be a string or null\"\n    );\n    anyhow::ensure!(\n        object.get(\"trader_id\").is_some_and(Value::is_string),\n        \"canonical trader ID must be a string\"\n    );\n    anyhow::ensure!(\n        matches!(\n            object.get(\"outcome\").and_then(Value::as_str),\n            Some(\"completed\" | \"failed\" | \"incomplete\" | \"stopped\")\n        ),\n        \"unsupported canonical run outcome\"\n    );\n    Ok(())\n}\n\nfn validate_unsigned_decimal(value: &Value, field: &str, nullable: bool) -> anyhow::Result<()> {\n    if nullable && value.is_null() {\n        return Ok(());\n    }\n    let value = value","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/backtest/src/result.rs#L440-L476","documentation":"`validate_run` requires the `trader_id` field of the canonical run object to be a JSON string. This error is thrown when the field exists but holds another JSON type (number, null, object, array) or is a non-string value. Trader IDs identify the trading node instance that produced the backtest result, and the canonical format mandates a string so consumers can parse them into the domain TraderId type.","triggerScenarios":"Passing a canonical result document to `validate_document` (via `validate_run`) where `run.trader_id` is not a JSON string — e.g. null, a number, or a nested object. Typically the document was not produced by this library's canonical serializer.","commonSituations":"Hand-built result JSON for testing; results migrated from an older format with a differently-typed trader identifier; a serialization tool that drops quotes around identifiers; fixtures copied from another schema.","solutions":["Set run.trader_id to the trader ID as a JSON string (e.g. \"TRADER-001\")","Regenerate the canonical document using the library's own result writer","Pre-validate the JSON and convert non-string trader IDs to strings before validation","Verify the source of the document matches the current canonical schema version"],"exampleFix":"// before\n{\"run\": {\"trader_id\": null, ...}}\n// after\n{\"run\": {\"trader_id\": \"TRADER-001\", ...}}","handlingStrategy":"validation","validationCode":"fn trader_id_is_valid(run: &serde_json::Value) -> bool {\n    run.get(\"trader_id\").is_some_and(serde_json::Value::is_string)\n}","typeGuard":"fn is_nonempty_string(v: &serde_json::Value) -> bool {\n    v.as_str().map_or(false, |s| !s.is_empty())\n}","tryCatchPattern":"match validate_document(&doc) {\n    Err(e) if e.to_string().contains(\"trader ID must be a string\") => {\n        // stringify run.trader_id and retry\n    }\n    other => other,\n}","preventionTips":["Serialize trader_id via its Display/to_string form","Never emit identifiers as raw JSON numbers","Validate fixtures against the current schema before use","Keep import/export code aware of the canonical field types"],"tags":["json","validation","schema","backtest"],"backgroundTag":"schema-validation-failed","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}