{"record":{"id":"6da7d3140264f931","repo":"vectordotdev/vector","slug":"failed-type-coercion-self-is-not-a-metric","errorCode":null,"errorMessage":"Failed type coercion, {self:?} is not a metric","messagePattern":"Failed type coercion, (.+?) is not a metric","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/vector-core/src/event/mod.rs","lineNumber":180,"sourceCode":"    /// Return self as a `LogEvent` if possible\n    ///\n    /// If the event is a `LogEvent`, then `Some(&log_event)` is returned, otherwise `None`.\n    pub fn maybe_as_log(&self) -> Option<&LogEvent> {\n        match self {\n            Event::Log(log) => Some(log),\n            _ => None,\n        }\n    }\n\n    /// Return self as a `Metric`\n    ///\n    /// # Panics\n    ///\n    /// This function panics if self is anything other than an `Event::Metric`.\n    pub fn as_metric(&self) -> &Metric {\n        match self {\n            Event::Metric(metric) => metric,\n            _ => panic!(\"Failed type coercion, {self:?} is not a metric\"),\n        }\n    }\n\n    /// Return self as a mutable `Metric`\n    ///\n    /// # Panics\n    ///\n    /// This function panics if self is anything other than an `Event::Metric`.\n    pub fn as_mut_metric(&mut self) -> &mut Metric {\n        match self {\n            Event::Metric(metric) => metric,\n            _ => panic!(\"Failed type coercion, {self:?} is not a metric\"),\n        }\n    }\n\n    /// Coerces self into `Metric`\n    ///\n    /// # Panics","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/vectordotdev/vector/blob/3708c39b12a93212ed8b8d7510b4cc7769cb5864/lib/vector-core/src/event/mod.rs#L162-L198","documentation":"`Event::as_metric` (lib/vector-core/src/event/mod.rs:172-181) borrows the event as `&Metric` and panics with a debug dump when the event is `Event::Log` or `Event::Trace`. Metric-oriented components (aggregations, metric sinks) rely on this precondition; code that cannot guarantee the variant must check first, since no fallible borrow twin exists for metrics in this impl.","triggerScenarios":"Calling `event.as_metric()` on a log event, e.g. a metrics aggregation transform or a Prometheus-style sink receiving logs because sources and sinks were wired into the same stream; trace events from an OTLP source hitting the same call.","commonSituations":"A pipeline where `stdin`/file/http log sources share a topology branch with a metrics sink; custom metric transforms reusing generic event loops; fixtures that build log events but exercise metric-only code paths.","solutions":["Guard with `matches!(event, Event::Metric(_))` before calling `as_metric`.","Branch on the variant and route non-metric events to their proper handler or drop them with an emitted error.","Split the topology so metrics sources and log sources feed separate pipelines."],"exampleFix":"// before\nlet metric = event.as_metric(); // panics on Log/Trace\n\n// after\nmatch &event {\n    Event::Metric(metric) => aggregate(metric),\n    other => emit!(UnexpectedEvent { event: &other }),\n}","handlingStrategy":"type-guard","validationCode":"if matches!(event, Event::Metric(_)) {\n    let metric = event.as_metric();\n}","typeGuard":"fn is_metric_event(e: &Event) -> bool { matches!(e, Event::Metric(_)) }","tryCatchPattern":null,"preventionTips":["Guard as_metric() with a variant check in any generic event loop.","Keep metric-only components on metrics-only pipeline branches.","Include log-event fixtures in metric component tests to catch unguarded coercions."],"tags":["rust","vector","event","metrics","type-coercion","panic"],"backgroundTag":"event-type-coercion-failure","analyzedSha":"3708c39b12a93212ed8b8d7510b4cc7769cb5864","analyzedAt":"2026-08-20T07:02:18.786Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}