vectordotdev/vector · error
Failed type coercion
Error message
Failed type coercion, {self:?} is not a Sink What it means
VectorSink::into_sink unwraps the VectorSink enum into its Sink variant (a Box<dyn Sink<EventArray>>), panicking if the sink was built as a Stream variant instead. VectorSink is built from a component's sink implementation, so this panic means the caller hardcoded an assumption about which style of sink the component builds.
Solutions
- Match on the VectorSink variant and call into_sink only for VectorSink::Sink
- Use VectorSink::run / run_events instead of unwrapping, which handles both variants
- In test code, construct the sink explicitly with VectorSink::from_event_sink to guarantee the Sink variant
Example fix
// before
let sink = vector_sink.into_sink();
// after
match vector_sink {
VectorSink::Sink(s) => /* use s */,
VectorSink::Stream(_) => panic!("expected event sink"),
}
// or generically:
vector_sink.run(input).await?; Defensive patterns
Strategy: type-guard
Validate before calling
assert!(matches!(vector_sink, VectorSink::Sink(_)), "expected event sink, got {:?}", vector_sink); Type guard
fn as_event_sink(s: VectorSink) -> Option<Box<dyn Sink<EventArray, Error = ()> + Send + Unpin>> {
match s {
VectorSink::Sink(sink) => Some(sink),
_ => None,
}
} Prevention
- Prefer VectorSink::run/run_events over into_sink/into_stream unwrapping
- Check whether the component builds its sink via from_event_sink vs from_event_streamsink before unwrapping
- Keep test harnesses variant-agnostic by dispatching on the enum
When it happens
Trigger: Calling VectorSink::into_sink on a sink built via VectorSink::from_event_streamsink / from_event_stream (the Stream variant), e.g. in custom sink drivers or tests that assume an event sink.
Common situations: Custom Vector builds or test harnesses that take a component's VectorSink and force it into a futures::Sink, while the component (most modern built-ins are stream-based) returned a StreamSink.
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
- Failed type coercion
- building HTTP request failed unexpectedly
- Failed type coercion
- Failed type coercion
- Failed type coercion
AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16).
Data as JSON: /api/errors/7a8aca70844c34f3.
Report an issue: GitHub.
Appendix: source
Thrown at lib/vector-core/src/sink.rs:49
///
/// See `VectorSink::run` for errors.
pub async fn run_events<I>(self, input: I) -> Result<(), ()>
where
I: IntoIterator<Item = Event> + Send,
I::IntoIter: Send,
{
self.run(stream::iter(input).map(Into::into)).await
}
/// Converts `VectorSink` into a `futures::Sink`
///
/// # 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]View on GitHub (pinned to bdb87aeaa4)