{"record":{"id":"a10018e6daad90d6","repo":"vectordotdev/vector","slug":"unexpected-metric","errorCode":null,"errorMessage":"unexpected metric","messagePattern":"unexpected metric","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/sinks/datadog/traces/sink.rs","lineNumber":48,"sourceCode":"pub(crate) struct PartitionKey {\n    pub(crate) api_key: Option<Arc<str>>,\n    pub(crate) env: Option<String>,\n    pub(crate) hostname: Option<String>,\n    pub(crate) agent_version: Option<String>,\n    // Those two last fields are configuration value and not a per-trace/span information, they come from the Datadog\n    // trace-agent config directly: https://github.com/DataDog/datadog-agent/blob/0f73a78/pkg/trace/config/config.go#L293-L294\n    pub(crate) target_tps: Option<i64>,\n    pub(crate) error_tps: Option<i64>,\n}\n\nimpl Partitioner for EventPartitioner {\n    type Item = Event;\n    type Key = PartitionKey;\n\n    fn partition(&self, item: &Self::Item) -> Self::Key {\n        match item {\n            Event::Metric(_) => {\n                panic!(\"unexpected metric\");\n            }\n            Event::Log(_) => {\n                panic!(\"unexpected log\");\n            }\n            Event::Trace(t) => PartitionKey {\n                api_key: item.metadata().datadog_api_key(),\n                env: t\n                    .get(event_path!(\"env\"))\n                    .map(|s| s.to_string_lossy().into_owned()),\n                hostname: log_schema().host_key().and_then(|key| {\n                    t.get((PathPrefix::Event, key))\n                        .map(|s| s.to_string_lossy().into_owned())\n                }),\n                agent_version: t\n                    .get(event_path!(\"agent_version\"))\n                    .map(|s| s.to_string_lossy().into_owned()),\n                target_tps: t\n                    .get(event_path!(\"target_tps\"))","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/vectordotdev/vector/blob/bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013/src/sinks/datadog/traces/sink.rs#L30-L66","documentation":"The Datadog traces sink is partitioned by API key and only accepts Trace events. Its Partitioner::partition implementation asserts the event kind: receiving a Metric or Log event is a programming/config error and panics immediately.","triggerScenarios":"An event of type Metric or Log reaches the datadog traces sink — typically via a misconfigured topology where a route or wildcard ('*') sends non-trace events into this sink, or a transform mislabels event types.","commonSituations":"A wildcard route matching all event types and one branch pointing at the traces sink; pipelines where logs are mistakenly routed to the traces sink; tests constructing the sink with synthetic non-trace events.","solutions":["Fix the topology so only Trace events reach the datadog traces sink (route explicitly on the event type)","Replace wildcard ('*') routes with explicit type-scoped routes, or add a filter/route transform checking .message_type or event kind before the sink","Run `vector validate` / `vector graph` to inspect which sources/transforms feed the sink","If the events are intended, use the datadog logs sink or metrics sink for those types instead"],"exampleFix":"// before (vector.toml style)\n[sinks.datadog_traces]\ninputs = [\"*\"]\n// after\n[sinks.datadog_traces]\ninputs = [\"traces_only\"]\n// where 'traces_only' is a route that passes only Trace events","handlingStrategy":"validation","validationCode":"// before wiring the sink, assert event kinds on the input path\nassert!(events.iter().all(|e| matches!(e, Event::Trace(_))), \"traces sink received non-trace events\");","typeGuard":"fn only_traces(events: &[Event]) -> bool { events.iter().all(|e| matches!(e, Event::Trace(_))) }","tryCatchPattern":null,"preventionTips":["Never use wildcard routes into type-specific sinks; route explicitly by event type","Add a filter/route transform before the sink that drops non-trace events","Run `vector validate` on the topology and review `vector top`/tap output for misrouted events","Keep unit tests for sink partitioners fed with representative events of the accepted type only"],"tags":["rust","panic","sinks","datadog","routing"],"backgroundTag":"incompatible-source-type","analyzedSha":"bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013","analyzedAt":"2026-09-16T02:53:35.741Z","contentChangedAt":"2026-09-16T02:53:35.741Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}