{"record":{"id":"d75fe5e5b3a77f42","repo":"nautechsystems/nautilus_trader","slug":"context-fields-do-not-match-the-version-1-schema","errorCode":null,"errorMessage":"{context} fields do not match the version 1 schema","messagePattern":"(.+?) fields do not match the version 1 schema","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/backtest/src/result.rs","lineNumber":364,"sourceCode":"    let summary = object\n        .get(\"summary\")\n        .and_then(Value::as_object)\n        .ok_or_else(|| anyhow::anyhow!(\"canonical result summary must be an object\"))?;\n    anyhow::ensure!(\n        summary.values().all(Value::is_string),\n        \"canonical result summary values must be strings\"\n    );\n    Ok(())\n}\n\nfn validate_fields(\n    object: &Map<String, Value>,\n    expected: &[&str],\n    context: &str,\n) -> anyhow::Result<()> {\n    let actual = object.keys().map(String::as_str).collect::<BTreeSet<_>>();\n    let expected = expected.iter().copied().collect::<BTreeSet<_>>();\n    anyhow::ensure!(\n        actual == expected,\n        \"{context} fields do not match the version 1 schema\"\n    );\n    Ok(())\n}\n\nfn validate_components(value: &Value) -> anyhow::Result<()> {\n    let object = value\n        .as_object()\n        .ok_or_else(|| anyhow::anyhow!(\"canonical result components must be an object\"))?;\n    validate_fields(\n        object,\n        &[\n            \"actor_ids\",\n            \"exec_algorithm_ids\",\n            \"strategy_ids\",\n            \"trader_state\",\n        ],","sourceCodeStart":346,"sourceCodeEnd":382,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/backtest/src/result.rs#L346-L382","documentation":"validate_fields compares the exact key set of a JSON object against the version 1 canonical schema's expected keys (order-insensitive, exact set equality). It throws when an object has a missing field, an extra/unknown field, or a typo'd key. It is shared by validate_document, validate_run, validate_statistics, validate_components, and validate_diagnostics, so the {context} prefix identifies which section mismatched.","triggerScenarios":"Parsing (from_slice) or constructing a document where any validated section (canonical result root, run, statistics, components, diagnostics entries) contains keys that differ from the schema — e.g. omitting 'trader_id' from 'run' or adding a custom 'notes' field.","commonSituations":"Hand-written or tool-generated result JSON with an added/renamed field; forward- or backward-compatible documents from a different schema version; typos like 'stategy_ids'.","solutions":["Diff the section's keys against the schema field list in the {context} message and add/remove fields to match exactly","Remove extra custom fields or rename misspelled keys to the exact schema names","Regenerate the document via the library instead of editing by hand","If the document is genuinely from another schema version, migrate it before parsing"],"exampleFix":"// before\n\"run\": {\"iterations\": \"1\", \"outcome\": \"completed\"} // missing fields\n// after\n\"run\": {\"backtest_end_ns\": null, \"backtest_start_ns\": null, \"iterations\": \"1\", \"outcome\": \"completed\", \"run_config_id\": null, \"total_events\": \"0\", \"total_orders\": \"0\", \"total_positions\": \"0\", \"trader_id\": \"TRADER-001\"}","handlingStrategy":"validation","validationCode":"fn keys_match(v: &serde_json::Value, expected: &[&str]) -> bool {\n    v.as_object().map_or(false, |o| {\n        let mut a: Vec<_> = o.keys().collect();\n        a.sort();\n        let mut e: Vec<_> = expected.iter().collect();\n        e.sort();\n        a == e\n    })\n}","typeGuard":null,"tryCatchPattern":"match CanonicalResult::from_slice(&bytes) {\n    Ok(result) => /* use result */,\n    Err(e) if e.to_string().contains(\"do not match the version 1 schema\") => {\n        // the message's {context} names the offending section; diff its keys and fix\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Copy field lists verbatim from the schema; never rename or add custom keys","Read the {context} prefix in the message to locate the offending section quickly","Validate all sections' key sets before calling from_slice when generating documents externally","Keep producer and consumer library versions in sync"],"tags":["json","schema-validation","strict-fields"],"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"}