{"record":{"id":"78158965123bedb3","repo":"vectordotdev/vector","slug":"message-must-exist-in-the-event","errorCode":null,"errorMessage":"`message` must exist in the event","messagePattern":"`message` must exist in the event","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/sources/docker_logs/mod.rs","lineNumber":1348,"sourceCode":"}\n\nfn line_agg_adapter(\n    inner: impl Stream<Item = LogEvent> + Unpin,\n    logic: line_agg::Logic<Bytes, LogEvent>,\n    log_namespace: LogNamespace,\n) -> impl Stream<Item = LogEvent> {\n    let line_agg_in = inner.map(move |mut log| {\n        let message_value = match log_namespace {\n            LogNamespace::Vector => log\n                .remove(&vrl::path::OwnedTargetPath::event_root())\n                .expect(\"`.` must exist in the event\"),\n            LogNamespace::Legacy => log\n                .remove(\n                    log_schema()\n                        .message_key_target_path()\n                        .expect(\"global log_schema.message_key to be valid path\"),\n                )\n                .expect(\"`message` must exist in the event\"),\n        };\n        let stream_value = match log_namespace {\n            LogNamespace::Vector => log\n                .get(metadata_path!(DockerLogsConfig::NAME, STREAM))\n                .expect(\"`docker_logs.stream` must exist in the metadata\"),\n            LogNamespace::Legacy => log\n                .get(event_path!(STREAM))\n                .expect(\"stream must exist in the event\"),\n        };\n\n        let stream = stream_value.coerce_to_bytes();\n        let message = message_value.coerce_to_bytes();\n        (stream, message, log)\n    });\n    let line_agg_out = LineAgg::<_, Bytes, LogEvent>::new(line_agg_in, logic);\n    line_agg_out.map(move |(_, message, mut log, _)| {\n        match log_namespace {\n            LogNamespace::Vector => log.insert(&vrl::path::OwnedTargetPath::event_root(), message),","sourceCodeStart":1330,"sourceCodeEnd":1366,"githubUrl":"https://github.com/vectordotdev/vector/blob/3708c39b12a93212ed8b8d7510b4cc7769cb5864/src/sources/docker_logs/mod.rs#L1330-L1366","documentation":"The Legacy branch of line_agg_adapter removes the message from the event via log.remove(message_key_target_path).expect(\"`message` must exist in the event\"). The docker_logs decoder inserted the message at exactly this path a few stages earlier, so the expect asserts an internal pipeline invariant; it panics when an event reaches the aggregator without a message field at the configured key.","triggerScenarios":"An upstream stage (or a regression) that produces LogEvents for this stream without the message field - for example partial-event merge state returning events that lost the message, or a log_schema message_key that diverges between the insert stage and this removal stage.","commonSituations":"Vector version changes touching log-namespace or partial-event handling; custom forks inserting extra stages between decode and aggregation.","solutions":["Confirm which stage drops the message by disabling multiline aggregation and checking event contents","Keep the global log_schema message_key at its default while using multiline on docker_logs","Patch: replace the expect with unwrap_or_default-style handling plus a warning","Report upstream with the config and upgrade"],"exampleFix":"// before\nLogNamespace::Legacy => log\n    .remove(\n        log_schema()\n            .message_key_target_path()\n            .expect(\"global log_schema.message_key to be valid path\"),\n    )\n    .expect(\"`message` must exist in the event\"),\n\n// after\nlet path = log_schema()\n    .message_key_target_path()\n    .unwrap_or_else(|| vrl::path::OwnedTargetPath::event_root());\nlet message_value = log\n    .remove(path)\n    .unwrap_or_else(|| Value::Bytes(Bytes::new()));","handlingStrategy":"validation","validationCode":"let path = log_schema()\n    .message_key_target_path()\n    .unwrap_or_else(|| vrl::path::OwnedTargetPath::event_root());\nif log.get(&path).is_none() {\n    warn!(message = \"event without message field; passing through\", ?path);\n    return log;\n}","typeGuard":"fn has_message_at(log: &LogEvent, path: &vrl::path::OwnedTargetPath) -> bool {\n    log.get(path).is_some()\n}","tryCatchPattern":"let message_value = log\n    .remove(path)\n    .unwrap_or_else(|| Value::Bytes(Bytes::new()));","preventionTips":["Ensure the insert stage and removal stage use the same resolved message path constant","Round-trip test multiline configs (insert then aggregate) for both namespaces","Bypass aggregation for events lacking the expected field instead of panicking"],"tags":["rust","panic","invariant","log-event","multiline","docker-logs"],"backgroundTag":"missing-event-field","analyzedSha":"3708c39b12a93212ed8b8d7510b4cc7769cb5864","analyzedAt":"2026-08-20T07:02:18.786Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}