vectordotdev/vector · error

`.` must exist in the event

Error message

`.` must exist in the event

What it means

When multiline aggregation is configured, docker_logs pipes events through line_agg_adapter. In the Vector log namespace it extracts the message from the event root with log.remove(&OwnedTargetPath::event_root()).expect("`.` must exist in the event") - the source inserted the message at the root a few stages earlier, so this is a pipeline-internal invariant. It panics when an event reaches the aggregator without a root value because some earlier stage produced or reshaped it differently.

Source

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

            labels,
            name: name.as_str().trim_start_matches('/').to_owned().into(),
            name_str: name,
            image: config.image.unwrap().into(),
            created_at: created.with_timezone(&Utc),
        })
    }
}

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();

View on GitHub (pinned to 3708c39b12)

Solutions

  1. Reproduce with multiline disabled to confirm the failing stage
  2. Keep log_namespace explicit and consistent for the source and retest
  3. Patch: replace remove(...).expect(...) with a fallback empty-bytes value and a warning
  4. Report with config + Vector version and upgrade

Example fix

// before
let message_value = log
    .remove(&vrl::path::OwnedTargetPath::event_root())
    .expect("`.` must exist in the event");

// after
let message_value = log
    .remove(&vrl::path::OwnedTargetPath::event_root())
    .unwrap_or_else(|| {
        warn!(message = "event missing root message before line_agg");
        Value::Bytes(Bytes::new())
    });
Defensive patterns

Strategy: validation

Validate before calling

// before the aggregator:
if log.get(&vrl::path::OwnedTargetPath::event_root()).is_none() {
    warn!(message = "event without root message; skipping line_agg");
    return log; // bypass aggregation
}

Type guard

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

Try / catch

let message_value = log
    .remove(&vrl::path::OwnedTargetPath::event_root())
    .unwrap_or_else(|| Value::Bytes(Bytes::new())); // or skip the event

Prevention

When it happens

Trigger: A Vector-internal regression or custom code path that feeds LogEvents into this stream without a root message (e.g. partial-event merge state mishandling), while multiline_config is enabled and log_namespace = true.

Common situations: Vector upgrades that changed log-namespace handling; combinations of log_namespace = true with multiline aggregation on docker_logs.

Related errors


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