{"record":{"id":"4fbf3dcdf3eb6003","repo":"vectordotdev/vector","slug":"inner-value-must-be-a-map","errorCode":null,"errorMessage":"inner value must be a map","messagePattern":"inner value must be a map","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/vector-core/src/event/trace.rs","lineNumber":28,"sourceCode":"use vrl::path::PathParseError;\n\nuse super::{\n    BatchNotifier, EstimatedJsonEncodedSizeOf, EventFinalizer, EventFinalizers, EventMetadata,\n    Finalizable, LogEvent, MergeFinalizable, ObjectMap, Value,\n};\n\n/// Traces are a newtype of `LogEvent`\n#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]\npub struct TraceEvent(LogEvent);\n\nimpl TraceEvent {\n    /// Convert a `TraceEvent` into a tuple of its components\n    /// # Panics\n    ///\n    /// Panics if the fields of the `TraceEvent` are not a `Value::Map`.\n    pub fn into_parts(self) -> (ObjectMap, EventMetadata) {\n        let (value, metadata) = self.0.into_parts();\n        let map = value.into_object().expect(\"inner value must be a map\");\n        (map, metadata)\n    }\n\n    pub fn from_parts(fields: ObjectMap, metadata: EventMetadata) -> Self {\n        Self(LogEvent::from_map(fields, metadata))\n    }\n\n    pub fn value(&self) -> &Value {\n        self.0.value()\n    }\n\n    pub fn value_mut(&mut self) -> &mut Value {\n        self.0.value_mut()\n    }\n\n    pub fn metadata(&self) -> &EventMetadata {\n        self.0.metadata()\n    }","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/vectordotdev/vector/blob/3708c39b12a93212ed8b8d7510b4cc7769cb5864/lib/vector-core/src/event/trace.rs#L10-L46","documentation":"TraceEvent is a newtype over LogEvent, and into_parts() assumes the inner event value is a Value::Map, calling value.into_object().expect(\"inner value must be a map\") (lib/vector-core/src/event/trace.rs). LogEvent is normally always constructed with a map (from_map/from_parts), so this panic fires only when a TraceEvent was materialized through a path that can hold a non-map value — e.g. deserializing a scalar into the inner LogEvent — violating the newtype's invariant.","triggerScenarios":"Calling TraceEvent::into_parts() on a TraceEvent whose inner LogEvent value is not Value::Map — typically a TraceEvent built via serde Deserialize from JSON that is a string/number/array rather than an object, or via LogEvent::new with a manually replaced scalar value. from_parts()-built events can never trigger it.","commonSituations":"Test code or embedding code that deserializes TraceEvents from payloads where the trace body is not a JSON object; interop code that converts arbitrary Values into TraceEvent without a map check. End-user Vector configs do not hit this in normal operation — it is an API-misuse/serialization-shape panic.","solutions":["Validate the payload shape before deserializing: require the top-level JSON value to be an object before constructing a TraceEvent","Build TraceEvents only via TraceEvent::from_parts(ObjectMap, metadata) or insertion APIs that keep the map invariant","If you deserialize untrusted data, match on the Value first and reject non-map values with an error instead of proceeding"],"exampleFix":"// before\nlet (map, metadata) = trace.into_parts();\n\n// after\nlet (value, metadata) = trace.into_parts_value();\nlet Some(map) = value.into_object() else {\n    return Err(\"trace event fields must be an object\");\n};","handlingStrategy":"type-guard","validationCode":"// Before calling into_parts, confirm the payload shape if it came from external data\nif !raw_json.is_object() {\n    return Err(DecodeError::new(\"trace payload must be a JSON object\"));\n}","typeGuard":"fn trace_is_map(trace: &TraceEvent) -> bool {\n    matches!(trace.value(), Value::Map(_))\n}","tryCatchPattern":null,"preventionTips":["Only construct TraceEvent via from_parts(ObjectMap, metadata)","Validate external payloads are objects at the trust boundary before deserializing into typed events","In tests, use TraceEvent::from_parts fixtures instead of serde-deserialized scalars"],"tags":["vector","trace-event","serde","type-invariant","panic"],"backgroundTag":"unexpected-value-type","analyzedSha":"3708c39b12a93212ed8b8d7510b4cc7769cb5864","analyzedAt":"2026-08-20T07:02:18.786Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}