{"record":{"id":"b9ba9b942102c0fb","repo":"vectordotdev/vector","slug":"failed-type-coercion-self-is-not-a-metric-ref","errorCode":null,"errorMessage":"Failed type coercion, {self:?} is not a metric reference","messagePattern":"Failed type coercion, (.+?) is not a metric reference","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/vector-core/src/event/ref.rs","lineNumber":52,"sourceCode":"    /// # Panics\n    ///\n    /// This will panic if this is not a `LogEvent` reference.\n    pub fn into_log(self) -> LogEvent {\n        match self {\n            Self::Log(log) => log.clone(),\n            _ => panic!(\"Failed type coercion, {self:?} is not a log reference\"),\n        }\n    }\n\n    /// Extract the `Metric` reference in this.\n    ///\n    /// # Panics\n    ///\n    /// This will panic if this is not a `Metric` reference.\n    pub fn as_metric(self) -> &'a Metric {\n        match self {\n            Self::Metric(metric) => metric,\n            _ => panic!(\"Failed type coercion, {self:?} is not a metric reference\"),\n        }\n    }\n\n    /// Convert this reference into a new `Metric` by cloning.\n    ///\n    /// # Panics\n    ///\n    /// This will panic if this is not a `Metric` reference.\n    pub fn into_metric(self) -> Metric {\n        match self {\n            Self::Metric(metric) => metric.clone(),\n            _ => panic!(\"Failed type coercion, {self:?} is not a metric reference\"),\n        }\n    }\n}\n\nimpl<'a> From<&'a Event> for EventRef<'a> {\n    fn from(event: &'a Event) -> Self {","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/vectordotdev/vector/blob/3708c39b12a93212ed8b8d7510b4cc7769cb5864/lib/vector-core/src/event/ref.rs#L34-L70","documentation":"EventRef::as_metric() extracts the &'a Metric from an EventRef, panicking unless the reference is the Metric variant. The panic is an invariant assertion: the API is designed for call sites that have already established the event is a metric, so any other variant reaching this code is a logic bug in the caller.","triggerScenarios":"Calling event_ref.as_metric() when the EventRef wraps a LogEvent or TraceEvent, e.g. metric-accumulator code fed from a logs source, or a match that falls through to a blanket coercion branch.","commonSituations":"Custom metric transforms or sinks connected to log inputs; code that inspects Event::as_log()/as_metric() based on a stale or wrong discriminant check; unit tests using mixed event fixtures where a log slips into the metric path.","solutions":["Narrow first: only call as_metric() when matches!(event_ref, EventRef::Metric(_))","Branch on the source Event with match event { Event::Metric(m) => ..., _ => ... } so the compiler guarantees the type","Fix the pipeline wiring so metric-only code only receives metrics (inputs/outputs declarations)"],"exampleFix":"// before\nlet metric = event_ref.as_metric(); // panics if not Metric\n\n// after\nif let EventRef::Metric(_) = event_ref {\n    let metric = event_ref.as_metric();\n    // ...\n}","handlingStrategy":"type-guard","validationCode":"if let EventRef::Metric(_) = event_ref {\n    let metric = event_ref.as_metric(); // safe\n}","typeGuard":"fn is_metric_ref(r: &EventRef<'_>) -> bool {\n    matches!(r, EventRef::Metric(_))\n}","tryCatchPattern":null,"preventionTips":["Match on the owning Event enum (Event::Metric arm) instead of coercing a shared reference","Keep metric-specific logic behind output-type declarations in pipeline config","Add tests covering mixed event arrays for any code that coerces references"],"tags":["rust","vector","event","metrics","type-coercion","panic"],"backgroundTag":"invalid-type-coercion","analyzedSha":"3708c39b12a93212ed8b8d7510b4cc7769cb5864","analyzedAt":"2026-08-20T07:02:18.786Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}