{"record":{"id":"3eef2b79ba898dbe","repo":"nautechsystems/nautilus_trader","slug":"unsupported-canonical-run-outcome","errorCode":null,"errorMessage":"unsupported canonical run outcome","messagePattern":"unsupported canonical run outcome","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/backtest/src/result.rs","lineNumber":462,"sourceCode":"        \"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\n        .as_str()\n        .ok_or_else(|| anyhow::anyhow!(\"canonical run field '{field}' must be a decimal string\"))?;\n    anyhow::ensure!(\n        value == \"0\"","sourceCodeStart":444,"sourceCodeEnd":480,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/backtest/src/result.rs#L444-L480","documentation":"The canonical run document's `outcome` field is restricted to the closed set of strings \"completed\", \"failed\", \"incomplete\", or \"stopped`. `validate_run` throws this error when `outcome` is any other string, a non-string value, or absent (though missing fields are normally caught earlier by validate_fields). It guarantees consumers can exhaustively match on run outcomes.","triggerScenarios":"Validating a canonical result where `run.outcome` is a value outside the allowed enum — e.g. \"ok\", \"success\", \"aborted\", an empty string, or a non-string such as null/number. Common when documents come from a different version or custom tooling that uses different outcome vocabulary.","commonSituations":"Custom backtest runners writing their own outcome strings; schema drift after the outcome enum was tightened in this version; translating results from another system (e.g. \"success\" vs \"completed\"); hand-edited fixtures.","solutions":["Map your outcome to one of the supported values: completed, failed, incomplete, stopped","Regenerate the result with the current library version so the canonical writer emits a valid outcome","Update translation/import code to normalize outcome strings before validation","Check the schema version of the input document against what this validator expects"],"exampleFix":"// before\n{\"run\": {\"outcome\": \"success\", ...}}\n// after\n{\"run\": {\"outcome\": \"completed\", ...}}","handlingStrategy":"validation","validationCode":"const OUTCOMES: &[&str] = &[\"completed\", \"failed\", \"incomplete\", \"stopped\"];\nfn outcome_is_valid(run: &serde_json::Value) -> bool {\n    run.get(\"outcome\")\n        .and_then(serde_json::Value::as_str)\n        .map_or(false, |o| OUTCOMES.contains(&o))\n}","typeGuard":"fn is_supported_outcome(v: &serde_json::Value) -> bool {\n    matches!(v.as_str(), Some(\"completed\" | \"failed\" | \"incomplete\" | \"stopped\"))\n}","tryCatchPattern":"match validate_document(&doc) {\n    Err(e) if e.to_string().contains(\"canonical run outcome\") => {\n        // normalize outcome string to the supported set and retry\n    }\n    other => other,\n}","preventionTips":["Use an enum for outcome in producing code and serialize via the canonical writer","Normalize foreign outcome vocabulary (success/ok) at import time","Keep a single source of truth for the outcome enum","Add a pre-validation step on imported result documents"],"tags":["validation","enum","schema","backtest"],"backgroundTag":"invalid-enum-value","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"}