{"record":{"id":"fc69c9cd12bc7edb","repo":"vectordotdev/vector","slug":"parent-id-should-be-an-i64","errorCode":null,"errorMessage":"`parent_id` should be an i64","messagePattern":"`parent_id` should be an i64","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/sinks/datadog/traces/apm_stats/weight.rs","lineNumber":29,"sourceCode":"    // TODO this logic likely has a bug(s) that need to be root caused. The root span is not reliably found and defaults to \"1.0\"\n    // regularly for users even when sampling is disabled in the Agent.\n    // GH issue to track that: https://github.com/vectordotdev/vector/issues/14859\n\n    if spans.is_empty() {\n        return 1.0;\n    }\n\n    let mut trace_id: Option<usize> = None;\n\n    let mut parent_id_to_child_weight = BTreeMap::<i64, f64>::new();\n    let mut span_ids = Vec::<i64>::new();\n    for s in spans.iter() {\n        // TODO these need to change to u64 when the following issue is fixed:\n        // https://github.com/vectordotdev/vector/issues/14687\n        let parent_id = match s.get(\"parent_id\") {\n            Some(Value::Integer(val)) => *val,\n            None => 0,\n            _ => panic!(\"`parent_id` should be an i64\"),\n        };\n        let span_id = match s.get(\"span_id\") {\n            Some(Value::Integer(val)) => *val,\n            None => 0,\n            _ => panic!(\"`span_id` should be an i64\"),\n        };\n        if trace_id.is_none() {\n            trace_id = match s.get(\"trace_id\") {\n                Some(Value::Integer(v)) => Some(*v as usize),\n                _ => panic!(\"`trace_id` should be an i64\"),\n            }\n        }\n        let weight = s\n            .get(\"metrics\")\n            .and_then(|m| m.as_object())\n            .map(|m| match m.get(SAMPLING_RATE_KEY) {\n                Some(Value::Float(v)) => {\n                    let sample_rate = v.into_inner();","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/vectordotdev/vector/blob/3708c39b12a93212ed8b8d7510b4cc7769cb5864/src/sinks/datadog/traces/apm_stats/weight.rs#L11-L47","documentation":"extract_weight_from_root_span() in the datadog_traces sink walks the span list to find the root span and compute its sampling weight. It reads 'parent_id' (and sibling fields 'span_id'/'trace_id') expecting Value::Integer or None (absent parent_id means root); a present-but-non-integer value hits the catch-all and panics. Note 'trace_id' is stricter: for the first span it must be present as an integer, otherwise the panic fires too.","triggerScenarios":"A span reaches the sink with 'parent_id' as a non-integer (float/string/bool) - e.g. IDs serialized through JSON as strings, or an OTLP mapping emitting 64-bit IDs as floats; or the first span lacking an integer 'trace_id'. The panic aborts APM stats computation for the batch.","commonSituations":"Trace pipelines that JSON-serialize/deserialize spans between source and sink (IDs become strings or lose integer precision); custom transforms re-inserting span ids with wrong types; version drift in OTLP ID handling (see vectordotdev/vector#14687 referenced in-code for the u64 follow-up).","solutions":["Keep spans on a native path from source to datadog_traces sink with no serialization round-trips or field rewrites","Where spans are constructed programmatically, write parent_id/span_id/trace_id as Value::Integer","Upgrade Vector - trace ID typing fixes are tracked upstream; check the changelog","Tap the stream (console sink) before the datadog sink to identify which spans carry non-integer IDs, then fix the producer"],"exampleFix":"// before\nspan.insert(\"parent_id\", Value::from(\"12345\")); // string id -> panic\n\n// after: IDs are i64 in the span map\nspan.insert(\"parent_id\", Value::Integer(12345));","handlingStrategy":"validation","validationCode":"fn ids_ok(span: &ObjectMap) -> bool {\n    matches!(span.get(\"parent_id\"), None | Some(Value::Integer(_)))\n        && matches!(span.get(\"span_id\"), None | Some(Value::Integer(_)))\n        && matches!(span.get(\"trace_id\"), Some(Value::Integer(_))) // first span must carry it\n}","typeGuard":"fn span_ids_are_i64(span: &ObjectMap) -> bool {\n    matches!(span.get(\"parent_id\"), None | Some(Value::Integer(_)))\n        && matches!(span.get(\"span_id\"), None | Some(Value::Integer(_)))\n}","tryCatchPattern":null,"preventionTips":["Write span ids as Value::Integer; never strings or floats","Do not serialize/deserialize span maps through JSON between source and the datadog sink","Ensure the first span of each trace carries an integer trace_id","Upgrade Vector when trace ID handling fixes land (u64 work tracked in vectordotdev/vector#14687)"],"tags":["rust","vector","datadog","traces","apm-stats","type-mismatch","panic"],"backgroundTag":"event-field-type-mismatch","analyzedSha":"3708c39b12a93212ed8b8d7510b4cc7769cb5864","analyzedAt":"2026-08-20T07:02:18.786Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T20:17:18.057Z"}