vectordotdev/vector · critical

output for default port required for task transforms

Error message

output for default port required for task transforms

What it means

When building a task (blocking) transform, the builder looks for an output with port == None (the default output) and .expect()s one exists, since task transforms may only write to the default output. Panicking here means a task transform's Outputs list lacks a default-port entry — an internal invariant or invalid component implementation.

Solutions

  1. Ensure the task transform declares exactly one default (unnamed port) output
  2. If the transform needs multiple outputs, do not build it as a task transform (use a regular/fan-out transform)
  3. Fix the component's outputs() implementation to include a None-port Output
  4. Report to the component author if triggered by a third-party transform

Example fix

// before
outputs: vec![Output::new(Port("secondary"), schema)]  // no default port
// after
outputs: vec![Output::default(Port(None), schema)]  // include default output
Defensive patterns

Strategy: type-guard

Validate before calling

// config-time guard: task transforms must expose a default output
assert!(outputs.iter().any(|o| o.port.is_none()), "task transform lacks default output");

Type guard

fn has_default_output(outputs: &[Output]) -> bool { outputs.iter().any(|o| o.port.is_none()) }

Prevention

When it happens

Trigger: A custom Transform implementation registered as a task transform that only declares named-port outputs (e.g. a route-style multi-output) without a default output; corrupted output metadata from a misbehaving component.

Common situations: Developers implementing custom task transforms in plugins/forks and wiring them to multiple named outputs; incorrect transform registration that marks a fan-out transform as a task transform.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at src/topology/builder.rs:955

            .filter(move |events| ready(filter_events_type(events, input_type)))
            .inspect(move |events| {
                events_received.emit(CountByteSize(
                    events.len(),
                    events.estimated_json_encoded_size_of(),
                ))
            });
        let events_sent = register!(EventsSent::from(internal_event::Output(None)));
        let output_id = Arc::new(OutputId {
            component: key.clone(),
            port: None,
        });
        let latency_recorder = LatencyRecorder::new(self.config.global.latency_ewma_alpha);

        // Task transforms can only write to the default output, so only a single schema def map is needed
        let schema_definition_map = outputs
            .iter()
            .find(|x| x.port.is_none())
            .expect("output for default port required for task transforms")
            .log_schema_definitions
            .clone()
            .into_iter()
            .map(|(key, value)| (key, Arc::new(value)))
            .collect();

        let stream = t
            .transform(Box::pin(filtered))
            .map(move |mut events| {
                for event in events.iter_events_mut() {
                    update_runtime_schema_definition(event, &output_id, &schema_definition_map);
                }
                let now = Instant::now();
                latency_recorder.on_send(&mut events, now);
                (events, now)
            })
            .inspect(move |(events, _): &(EventArray, Instant)| {
                events_sent.emit(CountByteSize(

View on GitHub (pinned to bdb87aeaa4)