vectordotdev/vector · error

Failed type coercion

Error message

Failed type coercion, {self:?} is not a Stream

What it means

VectorSink::into_stream unwraps the VectorSink enum into its Stream variant (a Box<dyn StreamSink<EventArray>>), panicking if the sink was built as the legacy Sink variant. The caller asserted the component produces a stream-style sink; the panic fires when it does not.

Solutions

  1. Match on VectorSink and only call into_stream for VectorSink::Stream
  2. Prefer VectorSink::run / run_events which dispatch correctly for both variants
  3. Replace uses of the deprecated VectorSink::from_event_sink with VectorSink::from_event_streamsink so the Stream variant is guaranteed

Example fix

// before
let stream = vector_sink.into_stream();
// after
match vector_sink {
    VectorSink::Stream(s) => /* use s */,
    VectorSink::Sink(_) => panic!("expected stream sink"),
}
// or generically:
vector_sink.run(input).await?;
Defensive patterns

Strategy: type-guard

Validate before calling

assert!(matches!(vector_sink, VectorSink::Stream(_)), "expected stream sink, got {:?}", vector_sink);

Type guard

fn as_stream_sink(s: VectorSink) -> Option<Box<dyn StreamSink<EventArray> + Send>> {
    match s {
        VectorSink::Stream(stream) => Some(stream),
        _ => None,
    }
}

Prevention

When it happens

Trigger: Calling VectorSink::into_stream on a sink built via the deprecated VectorSink::from_event_sink (the Sink variant), or on any component that still returns an event sink.

Common situations: Custom integrations/test harnesses written against stream sinks, run with a component or fixture built with the deprecated from_event_sink constructor.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16). Data as JSON: /api/errors/b3447693011461c2. Report an issue: GitHub.

Appendix: source

Thrown at lib/vector-core/src/sink.rs:61

    /// # Panics
    ///
    /// This function will panic if the self instance is not `VectorSink::Sink`.
    pub fn into_sink(self) -> Box<dyn Sink<EventArray, Error = ()> + Send + Unpin> {
        match self {
            Self::Sink(sink) => sink,
            _ => panic!("Failed type coercion, {self:?} is not a Sink"),
        }
    }

    /// Converts `VectorSink` into a `StreamSink`
    ///
    /// # Panics
    ///
    /// This function will panic if the self instance is not `VectorSink::Stream`.
    pub fn into_stream(self) -> Box<dyn StreamSink<EventArray> + Send> {
        match self {
            Self::Stream(stream) => stream,
            _ => panic!("Failed type coercion, {self:?} is not a Stream"),
        }
    }

    /// Converts an event sink into a `VectorSink`
    ///
    /// Deprecated in favor of `VectorSink::from_event_streamsink`. See [vector/9261]
    /// for more info.
    ///
    /// [vector/9261]: https://github.com/vectordotdev/vector/issues/9261
    #[deprecated]
    pub fn from_event_sink(sink: impl Sink<Event, Error = ()> + Send + Unpin + 'static) -> Self {
        VectorSink::Sink(Box::new(EventSink::new(sink)))
    }

    /// Converts an event stream into a `VectorSink`
    pub fn from_event_streamsink(sink: impl StreamSink<Event> + Send + 'static) -> Self {
        let sink = Box::new(sink);
        VectorSink::Stream(Box::new(EventStream { sink }))

View on GitHub (pinned to bdb87aeaa4)