{"record":{"id":"1daf5ce65dbdd8b3","repo":"vectordotdev/vector","slug":"cant-ever-be-empty","errorCode":null,"errorMessage":"cant ever be empty","messagePattern":"cant ever be empty","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/topology/builder.rs","lineNumber":689,"sourceCode":"        let enable_healthcheck = healthcheck.enabled && self.config.healthchecks.enabled;\n        let healthcheck_timeout = healthcheck.timeout;\n\n        let typetag = sink.inner.get_component_name();\n        let input_type = sink.inner.input().data_type();\n\n        // At this point, we've validated that all transforms are valid, including any\n        // transform that mutates the schema provided by their sources. We can now validate the\n        // schema expectations of each individual sink.\n        if let Err(mut err) =\n            schema::validate_sink_expectations(key, sink, self.config, enrichment_tables.clone())\n        {\n            self.errors.append(&mut err);\n        };\n\n        let (tx, rx) = match self.buffers.remove(key) {\n            Some(buffer) => buffer,\n            _ => {\n                let buffer_type = match sink.buffer.stages().first().expect(\"cant ever be empty\") {\n                    BufferType::Memory { .. } => \"memory\",\n                    BufferType::DiskV2 { .. } => \"disk\",\n                };\n                let buffer_span = error_span!(\"sink\", buffer_type);\n                let buffer = sink\n                    .buffer\n                    .build(\n                        self.config.global.data_dir.clone(),\n                        key.to_string(),\n                        buffer_span,\n                    )\n                    .await;\n                match buffer {\n                    Err(error) => {\n                        self.errors.push(format!(\"Sink \\\"{key}\\\": {error}\"));\n                        return;\n                    }\n                    Ok((tx, rx)) => (tx, Arc::new(Mutex::new(Some(rx.into_stream())))),","sourceCodeStart":671,"sourceCodeEnd":707,"githubUrl":"https://github.com/vectordotdev/vector/blob/bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013/src/topology/builder.rs#L671-L707","documentation":"While building a sink's buffer, the topology builder reads sink.buffer.stages().first() and .expect()s the stage list to be non-empty. A sink always has at least one buffer stage (validated at config time), so hitting this panic means an internal invariant was violated — the sink's buffer was accessed after its stages were removed/reset.","triggerScenarios":"Programmatic or corrupted configuration where a sink reaches build_sinks without any buffer stages; bugs in custom sink implementations that construct an empty BufferStage list; config altered between validation and build.","commonSituations":"Developers adding new sink types who forget to give the buffer a default stage; hand-edited or generated configs bypassing config validation; version-skew between config serialization and runtime expectations.","solutions":["Fix the sink/config so the buffer always has at least one stage (default memory buffer)","Ensure custom sinks initialize their buffer via the standard buffer config APIs","Re-validate the configuration so sinks with empty buffers are rejected before topology build","Report as a bug if a stock sink config triggers it — this is an internal invariant violation"],"exampleFix":"// before\nBufferStage list: [] (empty stages passed to sink buffer)\n// after\nbuffer: { stages: [{ type: \"memory\", ... }] }  // or default buffer","handlingStrategy":"type-guard","validationCode":"// config-time guard: every sink must declare at least one buffer stage\nassert!(!sink.buffer.stages().is_empty(), \"sink {} has no buffer stages\", key);","typeGuard":"fn has_buffer_stage(sink: &SinkConfig) -> bool { !sink.buffer.stages().is_empty() }","tryCatchPattern":null,"preventionTips":["Always give sinks a default memory buffer stage","Use the standard buffer config APIs in custom sink implementations","Keep config validation upstream of topology build so empty buffers fail early"],"tags":["rust","panic","internal","buffers"],"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"}