getsops/sops · error
Internal error: cannot find root
Error message
Internal error: cannot find root
What it means
unflattenTreeBranch asserts that the reconstructed root of the nested tree is a sops.TreeBranch (a map). This is a defensive internal invariant check: if convert() returned something that is not a TreeBranch, the flattening logic produced an unexpected shape and the function cannot return a valid TreeBranch.
Source
Thrown at stores/flatten.go:199
}
if key, ok := item.Key.(string); ok {
tokens := tokenize(key)
err := place(&item.Value, tokens, root)
if err != nil {
return nil, fmt.Errorf("Error while unflattening %q: %w", key, err)
}
} else {
return nil, fmt.Errorf("Found non-string key %q when unflattening", item.Key)
}
}
result, err := convert(root)
if err != nil {
return nil, fmt.Errorf("Error while unflattening: %w", err)
}
if tb, ok := result.(sops.TreeBranch); ok {
return tb, nil
}
return nil, fmt.Errorf("Internal error: cannot find root")
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Flatten
func flattenDescendValue(value interface{}, key string, destination sops.TreeBranch, destinationMap *map[string]bool) (sops.TreeBranch, error) {
switch value := value.(type) {
case sops.TreeBranch:
return flattenDescendMap(value, key+mapSeparator, destination, destinationMap)
case []interface{}:
return flattenDescendArray(value, key+listSeparator, destination, destinationMap)
}
if _, ok := (*destinationMap)[key]; ok {
return nil, fmt.Errorf("Found key collision %q while flattening", key)
}
destination = append(destination, sops.TreeItem{
Key: key,
Value: value,View on GitHub (pinned to 13442bb981)
Solutions
- Report/fix as a bug: inspect whether convert() returned a []interface{} (list-only root) or scalar and correct the node construction
- Check that at least one mapToken path exists in the flattened keys so the root builds subkeys
- Verify you are on an unmodified, released version of github.com/getsops/sops/v3/stores
Defensive patterns
Strategy: try-catch
Type guard
if tb, ok := result.(sops.TreeBranch); ok {
// safe to use tb
} Try / catch
tb, err := unflattenTreeBranch(branch)
if err != nil {
if err.Error() == "Internal error: cannot find root" {
return fmt.Errorf("internal sops bug, please report: %w", err)
}
return err
} Prevention
- Treat this as a library bug: file an issue with a reproducing branch
- Pin released versions of sops/v3
- Avoid forking/modifying stores/flatten.go internals
When it happens
Trigger: Practically unreachable in normal use because convert() returns sops.TreeBranch for a root with subkeys and TreeBranch{} for an empty root; it can only surface if convert's internal logic changes or a nil/degenerate node tree reaches the type assertion, i.e. a genuine bug in the stores package.
Common situations: Seen only when hacking on sops itself — modifying convert() or place() so the root node ends up holding only a scalar value or only list indices — or when bisecting an unexpected regression in the flatten/unflatten code.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Failed to read %q: %w
- Found non-string key %q when unflattening
- Error while unflattening: %w
- Found key collision %q while flattening
- Found non-string key %q when flattening
AI-assisted analysis of getsops/sops@13442bb981 (2026-09-01).
Data as JSON: /api/errors/ed721028868308d6.
Report an issue: GitHub.