vectordotdev/vector · error

Path cannot point directly to the root. Use `clear` instead.

Error message

Path cannot point directly to the root. Use `clear` instead.

What it means

`Renderer::delete` pops the last path segment as the key to delete and panics if none exists. Deleting requires a concrete key; a path pointing directly at the document root has nothing to remove, hence the message telling callers to use `clear` instead.

Solutions

  1. Call `clear` instead when the intent is to remove the entire document
  2. Ensure computed paths always end in a key before calling `delete`
  3. Add a pre-check that skips root-only paths or routes them to `clear`
  4. Trim and validate path input (require at least one non-empty segment)

Example fix

// before
renderer.delete("/");
// after
if path == "/" { renderer.clear(); } else { renderer.delete(&path); }
Defensive patterns

Strategy: validation

Validate before calling

fn route_delete(renderer: &Renderer, path: &str) {
    if path.split('/').all(|s| s.is_empty()) {
        renderer.clear();
    } else {
        renderer.delete(path);
    }
}

Prevention

When it happens

Trigger: Calling `delete` with a root-only path: `"/"`, an empty string, or any path with no segments after splitting on `/`.

Common situations: Dynamic deletion logic that computes paths from data and occasionally produces the bare root path, or a config/template that names no section to delete.

Related errors


AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16). Data as JSON: /api/errors/c82d5f9fbaa3c2dc. Report an issue: GitHub.

Appendix: source

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

    ///
    /// 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 delete(&mut self, path: &str) -> bool {
        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 cannot point directly to the root. Use `clear` instead.");

            // 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() {
                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."),
                    // If the next segment doesn't exist, there's nothing for us to delete, so return `false`.
                    None => return false,
                }
            }

            destination.remove(key).is_some()

View on GitHub (pinned to bdb87aeaa4)