{"record":{"id":"fb45677aae758ce2","repo":"nautechsystems/nautilus_trader","slug":"failed-to-parse-json-e","errorCode":null,"errorMessage":"Failed to parse JSON: {e}","messagePattern":"Failed to parse JSON: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/python/data/mod.rs","lineNumber":360,"sourceCode":"\n/// Deserializes JSON value to `CustomData` via the data class's `from_json`.\n#[cfg(feature = \"python\")]\nfn py_json_deserialize_custom_data(\n    data_class: &pyo3::Py<pyo3::PyAny>,\n    value: &serde_json::Value,\n) -> Result<std::sync::Arc<dyn crate::data::CustomDataTrait>, anyhow::Error> {\n    use std::sync::Arc;\n\n    use crate::data::PythonCustomDataWrapper;\n\n    pyo3::Python::attach(|py| {\n        let json_str = serde_json::to_string(&value)?;\n        let json_module = py\n            .import(\"json\")\n            .map_err(|e| anyhow::anyhow!(\"Failed to import json: {e}\"))?;\n        let py_dict = json_module\n            .call_method1(\"loads\", (json_str,))\n            .map_err(|e| anyhow::anyhow!(\"Failed to parse JSON: {e}\"))?;\n\n        let instance = data_class\n            .bind(py)\n            .call_method1(\"from_json\", (py_dict,))\n            .map_err(|e| anyhow::anyhow!(\"Failed to call from_json: {e}\"))?;\n\n        let wrapper = PythonCustomDataWrapper::new(py, &instance)\n            .map_err(|e| anyhow::anyhow!(\"Failed to create wrapper: {e}\"))?;\n\n        Ok(Arc::new(wrapper) as Arc<dyn crate::data::CustomDataTrait>)\n    })\n}\n\n/// Encodes `CustomData` items to `RecordBatch` via Python `encode_record_batch_py`.\n#[allow(unsafe_code)]\n#[cfg(all(feature = \"python\", feature = \"arrow\"))]\nfn py_encode_custom_data_to_record_batch(\n    items: &[std::sync::Arc<dyn crate::data::CustomDataTrait>],","sourceCodeStart":342,"sourceCodeEnd":378,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/python/data/mod.rs#L342-L378","documentation":"py_json_deserialize_custom_data converts the serialized JSON string into a Python dict via json.loads. If Python's json.loads rejects the string (should be rare since it was produced by serde_json, but possible with non-string keys/edge values or exotic floats), the error is wrapped as 'Failed to parse JSON: {e}'.","triggerScenarios":"Deserializing a custom data value whose serde JSON output Python's json.loads cannot parse — e.g. NaN/Infinity floats serialized by serde (invalid strict JSON for Python's parser), or a corrupted/too-deep payload.","commonSituations":"Custom data structs containing f64::NAN or INFINITY fields; extremely nested custom payloads hitting recursion limits; mismatched serde feature flags producing non-standard JSON.","solutions":["Sanitize custom data fields so they contain no NaN/Infinity values before deserialization.","Implement the custom data class's from_json to accept the dict and validate required fields.","Inspect the serialized string (serde_json::to_string(&value)) to confirm it is valid strict JSON.","Round-trip test the custom data type: serialize then deserialize in a unit test to catch schema drift."],"exampleFix":"// before: NaN breaks Python json.loads\n#[derive(Serialize)]\nstruct MyData { ratio: f64 } // ratio = f64::NAN\n// after: sanitize before serialization\n#[derive(Serialize)]\nstruct MyData { ratio: f64 }\nimpl MyData {\n    fn sanitized(mut self) -> Self {\n        if !self.ratio.is_finite() { self.ratio = 0.0; }\n        self\n    }\n}","handlingStrategy":"validation","validationCode":"// ensure all float fields are finite before deserialize path\nfn assert_finite(value: &serde_json::Value) -> bool {\n    match value {\n        serde_json::Value::Number(n) => n.as_f64().map(|f| f.is_finite()).unwrap_or(true),\n        serde_json::Value::Array(a) => a.iter().all(assert_finite),\n        serde_json::Value::Object(o) => o.values().all(assert_finite),\n        _ => true,\n    }\n}","typeGuard":null,"tryCatchPattern":"match py_json_deserialize_custom_data(data_class, value) {\n    Ok(v) => v,\n    Err(e) if e.to_string().contains(\"Failed to parse JSON\") => {\n        log::error!(\"payload not strict JSON: {}\", serde_json::to_string(&value).unwrap_or_default());\n        Err(e)\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Keep NaN/Infinity out of custom data fields.","Round-trip test each custom data type (serialize -> deserialize) in CI.","Avoid deeply nested payloads that hit Python recursion limits."],"tags":["python","json","custom-data","deserialization"],"backgroundTag":"json-parse-error","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"}