vectordotdev/vector · error
Path must end with a key.
Error message
Path must end with a key.
What it means
`Renderer::write` in the docs-renderer splits a slash-delimited path and pops the last segment as the target map key; it panics if there is no such segment. A path with no trailing key (e.g. `"/"` or `""`) has nowhere to write, so the operation is invalid by contract — paths must point at a concrete key below the root.
Solutions
- Ensure every path passed to `write` includes at least one segment after the leading `/` (e.g. `/section/key` not `/section` or `/`)
- Guard dynamic path construction: skip or special-case entries whose computed path ends at the root
- Validate/trim paths before calling and reject root-only paths early
- If the path should replace the whole document, use the appropriate root-level API instead of `write`
Example fix
// before
renderer.write("/", value);
// after
if path_segments.len() >= 2 {
renderer.write(&path, value);
} Defensive patterns
Strategy: validation
Validate before calling
fn is_writable_path(path: &str) -> bool {
path.split('/').any(|seg| !seg.is_empty())
} Prevention
- Always build paths with at least one key segment
- Avoid emitting root-only paths from dynamic doc generators
- Validate paths before calling renderer APIs
When it happens
Trigger: Calling `write` with a path that has no key segment after splitting on `/`: `"/"` (root only), an empty string, or a path consisting solely of slashes.
Common situations: Typically a bug in docs-generation code that computes paths dynamically, e.g. joining components and producing a bare `/` for top-level entries, or template/config data missing a section name.
Related errors
- Path cannot point directly to the root. Use `clear` instead.
- Failed to get extension for
- Failed to get file_name for
- non-utf8 path to pod logs dir is not supported
- not a valid path
AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16).
Data as JSON: /api/errors/882e6582b993d4b8.
Report an issue: GitHub.
Appendix: source
Thrown at lib/docs-renderer/src/renderer.rs:73
///
/// # Panics
///
/// If the path does not start with a forward slash, this method will panic. Likewise, if the
/// path is _only_ a forward slash (aka there is no segment to describe the key within the
/// object to write the value to), this method will panic.
///
/// If any nested object within the path does not yet exist, it will be created. If any segment,
/// other than the leaf segment, points to a value that is not an object/map, this method will
/// panic.
pub fn write<V: Into<Value>>(&mut self, path: &str, value: V) {
if !path.starts_with('/') {
panic!("Paths must always start with a leading forward slash (`/`).");
}
self.with_mut_object(|map| {
// Split the path, and take the last element as the actual map key to write to.
let mut segments = path.split('/').collect::<VecDeque<_>>();
let key = segments.pop_back().expect("Path must end with a key.");
// Iterate over the remaining elements, traversing into the root object one level at a
// time, based on using `token` as the map key. If there's no map at the given key,
// we'll create one. If there's something other than a map, we'll panic.
let mut destination = map;
while let Some(segment) = segments.pop_front() {
if destination.contains_key(segment) {
match destination.get_mut(segment) {
Some(Value::Object(next)) => {
destination = next;
continue;
}
Some(_) => {
panic!("Only leaf nodes should be allowed to be non-object values.")
}
None => unreachable!("Already asserted that the given key exists."),
}
} else {View on GitHub (pinned to bdb87aeaa4)