vectordotdev/vector · error

Key is not found: {:?}

Error message

Key is not found: {:?}

What it means

`LogEvent` implements `std::ops::Index` only under `#[cfg(any(test, feature = "test"))]` (lib/vector-core/src/event/log_event.rs:721-736) to give tests ergonomic `event["field"]` access. The index lookup goes through `parse_path_and_get_value`; if the path fails to parse or the key is absent, there is no `None` to return from `Index`, so it panics with the missing key. Production code is expected to use the fallible `get` API instead.

Source

Thrown at lib/vector-core/src/event/log_event.rs:728

    type Error = crate::Error;

    fn try_into(self) -> Result<serde_json::Value, Self::Error> {
        Ok(serde_json::to_value(&self.inner.fields)?)
    }
}

#[cfg(any(test, feature = "test"))]
impl<T> std::ops::Index<T> for LogEvent
where
    T: AsRef<str>,
{
    type Output = Value;

    fn index(&self, key: T) -> &Value {
        self.parse_path_and_get_value(key.as_ref())
            .ok()
            .flatten()
            .unwrap_or_else(|| panic!("Key is not found: {:?}", key.as_ref()))
    }
}

impl<K, V> Extend<(K, V)> for LogEvent
where
    K: AsRef<str>,
    V: Into<Value>,
{
    fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
        for (k, v) in iter {
            if let Ok(path) = parse_target_path(k.as_ref()) {
                self.insert(&path, v.into());
            }
        }
    }
}

// Allow converting any kind of appropriate key/value iterator directly into a LogEvent.

View on GitHub (pinned to 3708c39b12)

Solutions

  1. Use the fallible accessor in assertions: `event.get("message").expect("message set")` instead of `event["message"]`.
  2. Fix the fixture: insert the key (or fix the path string) so the lookup succeeds before indexing.
  3. For path lookups, prefer `event.get("a.b")` and assert on the returned `Option<&Value>` to get a clear failure message.

Example fix

// before
assert_eq!(event["message"], "hello"); // panics 'Key is not found' if unset

// after
assert_eq!(
    event.get("message").expect("message must be set").
        as_string_cloned().expect("message is a string"),
    "hello"
);
Defensive patterns

Strategy: type-guard

Validate before calling

if event.get("message").is_some() {
    assert_eq!(event["message"], "hello");
}

Type guard

fn has_key(event: &LogEvent, key: &str) -> bool { event.get(key).is_some() }

Prevention

When it happens

Trigger: In a test (or code built with the `test` feature), indexing an event at a key or path that was never inserted: `event["message"]` on an event built without `message`, or a malformed path like `"a..b"` that fails `parse_path_and_get_value`. The same code compiled without the `test` feature simply does not compile, so this panic is test-only.

Common situations: Unit tests where the fixture builder forgets to insert an asserted field; renaming a field in the code under test but not in the test's index expressions; tests using VRL-style path strings (`"a.b[0]"`) that do not parse as expected; enabling the `test` feature in CI integration code that then indexes optional fields.

Related errors


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