{"record":{"id":"747de2061f83cafd","repo":"vectordotdev/vector","slug":"span-must-already-exist","errorCode":null,"errorMessage":"span must already exist!","messagePattern":"span must already exist!","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/trace.rs","lineNumber":356,"sourceCode":"                        }\n                    }\n                }\n            }\n            // Try buffering the event, and if we're not buffering anymore, try to\n            // send it along via the trace sender if it's been established.\n            if !try_buffer_event(&log) {\n                try_broadcast_event(log);\n            }\n        }\n    }\n\n    fn on_new_span(\n        &self,\n        attrs: &tracing_core::span::Attributes<'_>,\n        id: &tracing_core::span::Id,\n        ctx: Context<'_, S>,\n    ) {\n        let span = ctx.span(id).expect(\"span must already exist!\");\n        let mut fields = SpanFields::default();\n        attrs.values().record(&mut fields);\n        span.extensions_mut().insert(fields);\n    }\n}\n\n#[derive(Default, Debug)]\nstruct SpanFields(HashMap<&'static str, Value>);\n\ninventory::submit!(SpanField(\"component_id\"));\ninventory::submit!(SpanField(\"component_type\"));\ninventory::submit!(SpanField(\"component_kind\"));\n\n/// Snapshot of every registered [`SpanField`],\n/// materialized once on first access. `inventory` populates submissions before `main`, so the\n/// snapshot is guaranteed to capture every entry; the read path on every traced span event is\n/// then a single set lookup against this static.\nstatic SPAN_FIELDS: LazyLock<HashSet<&'static str>> =","sourceCodeStart":338,"sourceCodeEnd":374,"githubUrl":"https://github.com/vectordotdev/vector/blob/bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013/src/trace.rs#L338-L374","documentation":"In the tracing `Layer`'s `on_new_span`, the code looks up the span by id with `ctx.span(id)` and expects it to exist since the callback fires for a newly created span. If the registry returns `None`, the `expect(\"span must already exist!\")` panics — a layer/registry invariant violation.","triggerScenarios":"A custom `Subscriber`/`Registry` combination where `Context::span(id)` returns `None` for a span id passed to `on_new_span`, e.g. a non-registry subscriber or spans being dropped concurrently with creation.","commonSituations":"Using this layer with a subscriber other than the tracing Registry it assumes; custom layering where span lifetimes are managed unusually; forks altering registry behavior.","solutions":["Use this layer with the standard `tracing_subscriber::Registry` it is designed for","Verify layer ordering (registry-based layers must sit above the Registry)","If using a custom subscriber, implement span lookup correctly or skip the extension insert","File a bug with subscriber setup if the standard registry still triggers it"],"exampleFix":"// before\nlet span = ctx.span(id).expect(\"span must already exist!\");\n// after\nif let Some(span) = ctx.span(id) {\n    span.extensions_mut().insert(fields);\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// narrow instead of expect\nfn span_fields<S>(ctx: &Context<'_, S>, id: &tracing_core::span::Id) -> Option<SpanFields> {\n    ctx.span(id).map(|span| {\n        let mut f = SpanFields::default();\n        span.extensions_mut().insert(f.clone());\n        f\n    })\n}","tryCatchPattern":null,"preventionTips":["Always pair the layer with tracing_subscriber::Registry","Check layer ordering relative to the Registry","Avoid custom subscribers unless span lookup is implemented","Replace expect with graceful skip when spans may be absent"],"tags":["rust","tracing","panic","subscriber"],"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"}