{"record":{"id":"fe524ce1ee0c30ac","repo":"vectordotdev/vector","slug":"output-for-default-port-required-for-task-transforms","errorCode":null,"errorMessage":"output for default port required for task transforms","messagePattern":"output for default port required for task transforms","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/topology/builder.rs","lineNumber":955,"sourceCode":"            .filter(move |events| ready(filter_events_type(events, input_type)))\n            .inspect(move |events| {\n                events_received.emit(CountByteSize(\n                    events.len(),\n                    events.estimated_json_encoded_size_of(),\n                ))\n            });\n        let events_sent = register!(EventsSent::from(internal_event::Output(None)));\n        let output_id = Arc::new(OutputId {\n            component: key.clone(),\n            port: None,\n        });\n        let latency_recorder = LatencyRecorder::new(self.config.global.latency_ewma_alpha);\n\n        // Task transforms can only write to the default output, so only a single schema def map is needed\n        let schema_definition_map = outputs\n            .iter()\n            .find(|x| x.port.is_none())\n            .expect(\"output for default port required for task transforms\")\n            .log_schema_definitions\n            .clone()\n            .into_iter()\n            .map(|(key, value)| (key, Arc::new(value)))\n            .collect();\n\n        let stream = t\n            .transform(Box::pin(filtered))\n            .map(move |mut events| {\n                for event in events.iter_events_mut() {\n                    update_runtime_schema_definition(event, &output_id, &schema_definition_map);\n                }\n                let now = Instant::now();\n                latency_recorder.on_send(&mut events, now);\n                (events, now)\n            })\n            .inspect(move |(events, _): &(EventArray, Instant)| {\n                events_sent.emit(CountByteSize(","sourceCodeStart":937,"sourceCodeEnd":973,"githubUrl":"https://github.com/vectordotdev/vector/blob/bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013/src/topology/builder.rs#L937-L973","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure the task transform declares exactly one default (unnamed port) output","If the transform needs multiple outputs, do not build it as a task transform (use a regular/fan-out transform)","Fix the component's outputs() implementation to include a None-port Output","Report to the component author if triggered by a third-party transform"],"exampleFix":"// before\noutputs: vec![Output::new(Port(\"secondary\"), schema)]  // no default port\n// after\noutputs: vec![Output::default(Port(None), schema)]  // include default output","handlingStrategy":"type-guard","validationCode":"// config-time guard: task transforms must expose a default output\nassert!(outputs.iter().any(|o| o.port.is_none()), \"task transform lacks default output\");","typeGuard":"fn has_default_output(outputs: &[Output]) -> bool { outputs.iter().any(|o| o.port.is_none()) }","tryCatchPattern":null,"preventionTips":["Implement outputs() for task transforms with a single unnamed default output","Use fan-out transforms, not task transforms, for multi-output components","Validate transform output contracts in component tests"],"tags":["rust","panic","internal","transforms"],"backgroundTag":"internal-invariant-violation","analyzedSha":"bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013","analyzedAt":"2026-09-16T02:53:35.741Z","contentChangedAt":"2026-09-16T02:53:35.741Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}