{"record":{"id":"a9c78c581957f46e","repo":"nautechsystems/nautilus_trader","slug":"failed-to-parse-decimal-value-e","errorCode":null,"errorMessage":"Failed to parse decimal '{value}': {e}","messagePattern":"Failed to parse decimal '(.+?)': (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/kraken/src/common/parse.rs","lineNumber":60,"sourceCode":"        enums::{\n            KrakenFuturesOrderEventType, KrakenInstrumentType, KrakenPositionSide,\n            KrakenSpotTrigger, KrakenTriggerSignal,\n        },\n    },\n    http::models::{\n        AssetPairInfo, FuturesFill, FuturesInstrument, FuturesOpenOrder, FuturesOrderEvent,\n        FuturesPosition, FuturesPublicExecution, OhlcData, SpotOrder, SpotTrade,\n    },\n};\n\n/// Parse a decimal string, handling empty strings and \"0\" values.\npub fn parse_decimal(value: &str) -> anyhow::Result<Decimal> {\n    if value.is_empty() || value == \"0\" {\n        return Ok(dec!(0));\n    }\n    value\n        .parse::<Decimal>()\n        .map_err(|e| anyhow::anyhow!(\"Failed to parse decimal '{value}': {e}\"))\n}\n\nfn parse_rfc3339_timestamp(value: &str, field: &str) -> anyhow::Result<UnixNanos> {\n    value\n        .parse::<UnixNanos>()\n        .map_err(|e| anyhow::anyhow!(\"Failed to parse {field}='{value}': {e}\"))\n}\n\n/// Normalizes a Kraken currency code by stripping the legacy X/Z prefix.\n///\n/// Kraken uses legacy prefixes for some currencies (e.g., XXBT for Bitcoin, XETH for Ethereum,\n/// ZUSD for USD). This function strips those prefixes for consistent lookups.\n#[inline]\npub fn normalize_currency_code(code: &str) -> &str {\n    code.strip_prefix(\"X\")\n        .or_else(|| code.strip_prefix(\"Z\"))\n        .unwrap_or(code)\n}","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/kraken/src/common/parse.rs#L42-L78","documentation":"parse_decimal converts a Kraken API string into a fixed-precision Decimal; this error is raised when the string fails Decimal::parse. Empty strings and \"0\" are normalized to 0 beforehand, so the failure means the exchange returned a value the parser cannot interpret. It is a data-format error, not an arithmetic error.","triggerScenarios":"parse_decimal receiving a non-numeric or badly formatted string (e.g. \"1,234.5\", \"12.3.4\", \"NaN\", locale-formatted values) from parse_decimal_opt, compute_avg_px, or parse_fill_report.","commonSituations":"Kraken changing a field's format or emitting null-ish placeholders; a caller passing already-localized strings; SDK/API version drift where a field switched from number-string to scientific notation.","solutions":["Log and inspect the offending raw value to confirm the exact format Kraken returned.","Normalize the input (strip thousands separators, expand scientific notation) before calling parse_decimal.","Use parse_decimal_opt and treat unparseable values as absent rather than failing the whole message.","Update the adapter if a Kraken API format change is the cause."],"exampleFix":"// before\nlet qty = parse_decimal(fill[\"vol\"])?;\n// after\nlet qty = match parse_decimal_opt(fill[\"vol\"]) {\n    Some(d) if d > dec!(0) => d,\n    _ => { tracing::warn!(raw = %fill[\"vol\"], \"unparseable fill volume, skipping\"); return Ok(None); }\n};","handlingStrategy":"validation","validationCode":"// Rust: pre-validate exchange numeric strings\nfn is_parseable_decimal(s: &str) -> bool {\n    !s.is_empty() && s != \"0\" && s.parse::<rust_decimal::Decimal>().is_ok()\n}","typeGuard":null,"tryCatchPattern":"match parse_decimal(raw) {\n    Ok(d) => d,\n    Err(e) => { tracing::warn!(\"bad decimal {e}; skipping record\"); return Ok(None); }\n}","preventionTips":["Use parse_decimal_opt for optional or best-effort fields.","Log the raw value on failure to detect exchange format drift early.","Normalize locale separators and scientific notation before parsing.","Add integration fixtures for real Kraken payloads."],"tags":["parsing","decimal","kraken","data-format"],"backgroundTag":"invalid-argument-format","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"}