vectordotdev/vector · error

`message` must exist in the event

Error message

`message` must exist in the event

What it means

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.

Source

Thrown at src/sources/docker_logs/mod.rs:1348

}

fn line_agg_adapter(
    inner: impl Stream<Item = LogEvent> + Unpin,
    logic: line_agg::Logic<Bytes, LogEvent>,
    log_namespace: LogNamespace,
) -> impl Stream<Item = LogEvent> {
    let line_agg_in = inner.map(move |mut log| {
        let message_value = match log_namespace {
            LogNamespace::Vector => log
                .remove(&vrl::path::OwnedTargetPath::event_root())
                .expect("`.` must exist in the event"),
            LogNamespace::Legacy => log
                .remove(
                    log_schema()
                        .message_key_target_path()
                        .expect("global log_schema.message_key to be valid path"),
                )
                .expect("`message` must exist in the event"),
        };
        let stream_value = match log_namespace {
            LogNamespace::Vector => log
                .get(metadata_path!(DockerLogsConfig::NAME, STREAM))
                .expect("`docker_logs.stream` must exist in the metadata"),
            LogNamespace::Legacy => log
                .get(event_path!(STREAM))
                .expect("stream must exist in the event"),
        };

        let stream = stream_value.coerce_to_bytes();
        let message = message_value.coerce_to_bytes();
        (stream, message, log)
    });
    let line_agg_out = LineAgg::<_, Bytes, LogEvent>::new(line_agg_in, logic);
    line_agg_out.map(move |(_, message, mut log, _)| {
        match log_namespace {
            LogNamespace::Vector => log.insert(&vrl::path::OwnedTargetPath::event_root(), message),

View on GitHub (pinned to 3708c39b12)

Solutions

  1. Confirm which stage drops the message by disabling multiline aggregation and checking event contents
  2. Keep the global log_schema message_key at its default while using multiline on docker_logs
  3. Patch: replace the expect with unwrap_or_default-style handling plus a warning
  4. Report upstream with the config and upgrade

Example fix

// before
LogNamespace::Legacy => log
    .remove(
        log_schema()
            .message_key_target_path()
            .expect("global log_schema.message_key to be valid path"),
    )
    .expect("`message` must exist in the event"),

// after
let path = log_schema()
    .message_key_target_path()
    .unwrap_or_else(|| vrl::path::OwnedTargetPath::event_root());
let message_value = log
    .remove(path)
    .unwrap_or_else(|| Value::Bytes(Bytes::new()));
Defensive patterns

Strategy: validation

Validate before calling

let path = log_schema()
    .message_key_target_path()
    .unwrap_or_else(|| vrl::path::OwnedTargetPath::event_root());
if log.get(&path).is_none() {
    warn!(message = "event without message field; passing through", ?path);
    return log;
}

Type guard

fn has_message_at(log: &LogEvent, path: &vrl::path::OwnedTargetPath) -> bool {
    log.get(path).is_some()
}

Try / catch

let message_value = log
    .remove(path)
    .unwrap_or_else(|| Value::Bytes(Bytes::new()));

Prevention

When it happens

Trigger: 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.

Common situations: Vector version changes touching log-namespace or partial-event handling; custom forks inserting extra stages between decode and aggregation.

Related errors


AI-assisted analysis of vectordotdev/vector@3708c39b12 (2026-08-20). Data as JSON: /api/errors/78158965123bedb3. Report an issue: GitHub.