t8y2/dbx · error
Root znode cannot be deleted
Error message
Root znode cannot be deleted
What it means
delete normalizes the request key into a znode path and refuses to delete the root: if path == "/" it returns 'Root znode cannot be deleted'. Deleting / would be destructive/invalid, so the driver rejects it before touching the server.
Source
Thrown at agents/drivers/zookeeper/operations.go:217
if _, err := client.Create(current, nil, 0); err != nil && err != zk.ErrNodeExists {
return err
}
}
return nil
}
func (service *server) delete(params json.RawMessage) (map[string]any, error) {
client, err := service.requireClient()
if err != nil {
return nil, err
}
var request deleteRequest
if err := json.Unmarshal(params, &request); err != nil {
return nil, err
}
path := normalizePath(request.Key)
if path == "/" {
return nil, errors.New("Root znode cannot be deleted")
}
exists, _, err := client.Exists(path)
if err != nil {
return nil, err
}
if !exists {
return map[string]any{"deleted": 0}, nil
}
if !request.Recursive {
if err := client.Delete(path); err != nil {
if err == zk.ErrNoNode {
return map[string]any{"deleted": 0}, nil
}
return nil, err
}
return map[string]any{"deleted": 1}, nil
}
deleted, err := deleteSubtree(client, path)View on GitHub (pinned to c0390bff16)
Solutions
- Pass a specific child path, e.g. "/myapp/config", never "/".
- Add caller-side validation rejecting empty or "/" keys before delete.
- If you intended to wipe an application subtree, delete that subtree's parent znode instead of the root.
- Review recursive cleanup loops to ensure they never start at "/".
Example fix
// before driver.Delete(ctx, "/") // rejected // after driver.Delete(ctx, "/myapp/tmp-node")
Defensive patterns
Strategy: validation
Validate before calling
func validateDeleteKey(key string) error {
k := strings.TrimSpace(key)
if k == "" || k == "/" {
return errors.New("zookeeper delete key must identify a non-root znode")
}
return nil
} Try / catch
if err := validateDeleteKey(key); err != nil { return err }
err := driver.Delete(ctx, key)
if err != nil && strings.Contains(err.Error(), "Root znode cannot be deleted") {
return fmt.Errorf("refusing to delete znode root: %w", err)
} Prevention
- Never start recursive cleanup at "/"
- Reject empty or "/" keys before calling delete
- Scope deletes under an application namespace prefix
- Code-review any 'purge'/'clear' feature for root-path handling
When it happens
Trigger: Calling delete (directly or via dispatch) with Key = "/" or an empty key that normalizePath maps to "/". Raised in agents/drivers/zookeeper/operations.go:217.
Common situations: Recursive-delete helper that started at the root; an empty key after trimming in caller code; a 'clear namespace' feature that mistakenly targets "/"; path-building bugs where the namespace prefix was lost.
Related errors
- Root znode cannot be modified
- Unsupported createMode: %s
- ZooKeeper server list is empty
- ZooKeeper auth scheme and credentials must be configured tog
- Unsupported auth_scheme %q; expected %q or %q
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/ce4500056ad2b6bc.
Report an issue: GitHub.