{"record":{"id":"fba2eba8a70b9769","repo":"dbt-labs/dbt-core","slug":"failed-to-serialize-core-event-info-to-json","errorCode":null,"errorMessage":"Failed to serialize core event info to JSON","messagePattern":"Failed to serialize core event info to JSON","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/dbt-common/src/tracing/layers/json_compat_layer.rs","lineNumber":1085,"sourceCode":"                // In debug build panic for unknown codes to catch missing mappings, in prod just skip\n                #[cfg(debug_assertions)]\n                panic!(\n                    \"Unhandled dbt_core_event_code '{}' in ProgressMessage. Add mapping in JsonCompatLayer `emit_progress_message` function.\",\n                    progress_msg.dbt_core_event_code.as_deref().unwrap()\n                );\n                #[cfg(not(debug_assertions))]\n                return;\n            }\n            None => (None, None), // Fall back to generic handling\n        };\n\n        let info_json = serde_json::to_value(self.build_core_event_info(\n            event_code,\n            event_name,\n            &log_record.severity_text,\n            msg.clone(),\n        ))\n        .expect(\"Failed to serialize core event info to JSON\");\n\n        let mut data_obj = json!({\n            \"msg\": msg,\n        });\n\n        // Include unique_id in node_info if available\n        if let Some(unique_id) = progress_msg.unique_id.as_deref() {\n            data_obj.as_object_mut().unwrap().insert(\n                \"node_info\".to_string(),\n                json!({\n                    \"unique_id\": unique_id\n                }),\n            );\n        }\n\n        let value = json!({\n            \"info\": info_json,\n            \"data\": data_obj","sourceCodeStart":1067,"sourceCodeEnd":1103,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-common/src/tracing/layers/json_compat_layer.rs#L1067-L1103","documentation":"The JSON compat layer builds a dbt-core-style CoreEventInfo struct for a progress/log event and converts it with serde_json::to_value, unwrapping via .expect. Panicking here means serde_json could not serialize the struct, an internal invariant violation since all CoreEventInfo fields are plain strings/ints plus an `extra` map of custom env values.","triggerScenarios":"on_log_record -> emit_progress_message runs while the JSON compat layer is active (json/machine output format) and the CoreEventInfo payload fails to serialize — practically only when a custom env entry injected into `extra` is not JSON-representable (non-string map key or non-finite float like NaN) or struct invariants are broken by a code change.","commonSituations":"Running dbt with --log-format json / machine output in CI; injecting custom env vars for log enrichment containing non-finite floats or exotic types; upgrading dbt-common after touching the tracing code.","solutions":["Inspect the custom envs fed to JsonCompatLayer and ensure they are JSON-safe values (string keys, no NaN/Infinity)","Replace the .expect with graceful handling that logs the event without the info block instead of aborting the run","Reproduce with RUST_BACKTRACE=1 and check which CoreEventInfo field fails; fix the type at the source"],"exampleFix":"// before\nlet info_json = serde_json::to_value(self.build_core_event_info(\n    event_code,\n    event_name,\n    &log_record.severity_text,\n    msg.clone(),\n))\n.expect(\"Failed to serialize core event info to JSON\");\n// after\nlet info_json = serde_json::to_value(self.build_core_event_info(\n    event_code,\n    event_name,\n    &log_record.severity_text,\n    msg.clone(),\n))\n.unwrap_or(serde_json::Value::Null);","handlingStrategy":"fallback","validationCode":"fn is_json_safe(v: &serde_json::Value) -> bool {\n    use serde_json::Value;\n    match v {\n        Value::Null | Value::Bool(_) | Value::String(_) | Value::Number(_) => true,\n        Value::Array(a) => a.iter().all(is_json_safe),\n        Value::Object(m) => m.iter().all(|(_k, v)| is_json_safe(v)),\n    }\n}\n// assert every custom env value is_json_safe before constructing JsonCompatLayer","typeGuard":null,"tryCatchPattern":"let info_json = serde_json::to_value(info).unwrap_or(serde_json::Value::Null);","preventionTips":["Only pass JSON-serializable custom env values (string keys, finite numbers) to the tracing layer","Add a round-trip unit test serializing CoreEventInfo in CI","Prefer unwrap_or(Value::Null) + warn over .expect in logging hot paths"],"tags":["panic","serialization","json","tracing"],"backgroundTag":"json-marshal-failed","analyzedSha":"0267ce9170576975b76b64ce856b2e5848e96617","analyzedAt":"2026-09-07T21:53:39.732Z","contentChangedAt":"2026-09-07T21:53:39.732Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}