{"record":{"id":"0224e0406c5e64f4","repo":"nautechsystems/nautilus_trader","slug":"customdata-value-must-be-valid-json-e","errorCode":null,"errorMessage":"CustomData value must be valid JSON: {e}","messagePattern":"CustomData value must be valid JSON: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/infrastructure/src/sql/queries.rs","lineNumber":1622,"sourceCode":"        .bind(name)\n        .fetch_all(pool)\n        .await\n        .map(|rows| rows.into_iter().map(|row| row.0).collect())\n        .map_err(|e| anyhow::anyhow!(\"Failed to load signals: {e}\"))\n    }\n\n    /// Inserts a `CustomData` entry via the provided `pool`.\n    ///\n    /// Serializes the model `CustomData` to full JSON and stores it in the JSONB `value` column.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the SQL INSERT operation fails.\n    pub async fn add_custom_data(pool: &PgPool, data: &CustomData) -> anyhow::Result<()> {\n        let json_bytes = serde_json::to_vec(data)\n            .map_err(|e| anyhow::anyhow!(\"CustomData must be valid JSON: {e}\"))?;\n        let value_json: serde_json::Value = serde_json::from_slice(&json_bytes)\n            .map_err(|e| anyhow::anyhow!(\"CustomData value must be valid JSON: {e}\"))?;\n        let data_type_obj = value_json\n            .get(\"data_type\")\n            .and_then(|v| v.as_object())\n            .ok_or_else(|| anyhow::anyhow!(\"CustomData JSON missing data_type\"))?;\n        let data_type_name = data_type_obj\n            .get(\"type_name\")\n            .and_then(|v| v.as_str())\n            .unwrap_or(\"\");\n        let metadata_json = data_type_obj\n            .get(\"metadata\")\n            .cloned()\n            .unwrap_or_else(|| serde_json::Value::Object(serde_json::Map::new()));\n        let identifier = data_type_obj\n            .get(\"identifier\")\n            .and_then(|v| v.as_str())\n            .unwrap_or(\"\");\n        sqlx::query(\n            r#\"","sourceCodeStart":1604,"sourceCodeEnd":1640,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/infrastructure/src/sql/queries.rs#L1604-L1640","documentation":"Raised in `add_custom_data` when the freshly serialized CustomData bytes fail to parse back via `serde_json::from_slice`. This is a defensive round-trip check before extracting the `data_type` field; failure indicates the serialized bytes are not valid JSON (rare, usually a bug or non-UTF8/binary payload) .","triggerScenarios":"Calling `add_custom_data` when serialization produced bytes that serde_json cannot parse back — e.g., a custom Serialize impl emitting invalid JSON, or corrupted intermediate representation.","commonSituations":"Hand-written Serialize implementations producing malformed output; exotic custom data payloads; library version mismatch where CustomData's serialized shape changed.","solutions":["Confirm the payload serializes and deserializes cleanly with serde_json::to_vec/from_slice in a unit test.","Inspect the serde_json error in `{e}` for the offset of the invalid byte.","Avoid custom Serialize impls; derive Serialize/Deserialize on the payload type.","Update to matching versions of the data model crate so serialization output is well-formed."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"let bytes = serde_json::to_vec(&data)?;\nserde_json::from_slice::<serde_json::Value>(&bytes)\n    .map_err(|e| anyhow::anyhow!(\"payload does not round-trip: {e}\"))?;","typeGuard":"fn round_trips<T: serde::Serialize>(v: &T) -> bool {\n    serde_json::to_vec(v)\n        .ok()\n        .map(|b| serde_json::from_slice::<serde_json::Value>(&b).is_ok())\n        .unwrap_or(false)\n}","tryCatchPattern":null,"preventionTips":["Unit-test Serialize/Deserialize round-trips for custom data types","Avoid custom Serialize impls emitting non-standard JSON","Keep the data model crate versions consistent"],"tags":["serde","json","roundtrip"],"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"}