vectordotdev/vector · error

Only leaf nodes should be allowed to be non-object values.

Error message

Only leaf nodes should be allowed to be non-object values.

What it means

While walking the intermediate segments of a path, `Renderer::write` in lib/docs-renderer requires every non-leaf node to be a JSON object so it can descend one level at a time. If an intermediate segment already holds a scalar/array value, there is nowhere to descend and the method panics with this assertion. Leaf segments are the only place non-object values may live.

Source

Thrown at lib/docs-renderer/src/renderer.rs:87

        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 {
                    destination.insert(segment.to_string(), Value::Object(Map::new()));
                    match destination.get_mut(segment) {
                        Some(Value::Object(next)) => {
                            destination = next;
                        }
                        _ => panic!("New object was just inserted."),
                    }
                }
            }

            destination.insert(key.to_string(), value.into());
        });
    }

View on GitHub (pinned to 3708c39b12)

Solutions

  1. Keep paths consistent: choose either `/a` as a leaf or `/a/...` as a branch, never both over time.
  2. Call `renderer.delete("/a")` (or `clear`) before restructuring a scalar leaf into an object parent.
  3. Write parent objects before their leaves and assert `renderer.get("/a")` is absent or an object before deeper writes.

Example fix

// before
renderer.write("/function", Value::String(name.clone()));
renderer.write("/function/aliases", aliases); // panic: /function is a string

// after
renderer.write("/function/name", Value::String(name));
renderer.write("/function/aliases", aliases);
Defensive patterns

Strategy: type-guard

Validate before calling

if let Some(existing) = renderer.get(parent_path) {
    if !existing.is_object() {
        renderer.delete(parent_path); // clear the scalar before nesting under it
    }
}
renderer.write(full_path, value);

Type guard

fn segment_is_object(v: Option<&Value>) -> bool {
    v.map(|v| v.is_object()).unwrap_or(true)
}

Prevention

When it happens

Trigger: Sequence like `renderer.write("/a", "scalar")` followed by `renderer.write("/a/b", 1)` — segment `a` is a string, so descending to `b` panics. Also triggered by writing `/root/nested/key` after `root` was previously set to an array or scalar.

Common situations: Generated-docs code that first writes a summary string under a key and later tries to hang structured sub-keys under the same key; merging two data sources that disagree on whether a path is a leaf; refactoring a flat key into a nested object without clearing the old value first.

Related errors


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