getsops/sops · error
Unexpected key type %T
Error message
Unexpected key type %T
What it means
Raised inside sopsToGoMap while converting a sops tree branch into plain Go maps: a tree item key is neither a sops.Comment nor a string. The JSON/YAML stores only produce string keys, so this signals a tree built or mutated with a non-string key type.
Source
Thrown at stores/metadata.go:50
// Only used if Flatten is not MetadataFlattenNone.
// This does provide a double escape for newlines, since the store itself
// is already expected to take care of them. This is mainly needed for
// backwards compatibility with the INI store.
EscapeNewlines bool
}
// SopsPrefix is the prefix for all metadata entry keys.
const SopsPrefix = SopsMetadataKey + "_"
func sopsToGoMap(mapping sops.TreeBranch) (map[string]interface{}, error) {
result := make(map[string]interface{})
for _, item := range mapping {
if _, ok := item.Key.(sops.Comment); ok {
continue
}
key, ok := item.Key.(string)
if !ok {
return nil, fmt.Errorf("Unexpected key type %T", item.Key)
}
value, err := sopsToGo(item.Value)
if err != nil {
return nil, err
}
result[key] = value
}
return result, nil
}
func sopsToGoSlice(slice []interface{}) ([]interface{}, error) {
result := make([]interface{}, 0, len(slice))
for _, item := range slice {
if _, ok := item.(sops.Comment); ok {
continue
}
value, err := sopsToGo(item)
if err != nil {View on GitHub (pinned to 13442bb981)
Solutions
- Convert all TreeItem keys to strings before conversion: fmt.Sprint(key) or string coercion
- Skip/strip non-string key items from the branch before conversion
- Fix the upstream code that inserts non-string keys into the tree
Example fix
// before
branch = append(branch, sops.TreeItem{Key: 42, Value: v})
// after
branch = append(branch, sops.TreeItem{Key: strconv.Itoa(42), Value: v}) Defensive patterns
Strategy: type-guard
Validate before calling
func allStringKeys(branch sops.TreeBranch) bool {
for _, item := range branch {
if _, ok := item.Key.(string); !ok {
return false
}
}
return true
} Type guard
func isStringKey(k interface{}) bool {
_, ok := k.(string)
return ok
} Try / catch
result, err := sopsToGo(branch)
if err != nil {
if strings.HasPrefix(err.Error(), "Unexpected key type") {
return fmt.Errorf("tree built with non-string key: %w", err)
}
return err
} Prevention
- Only build tree branches with string keys
- Coerce non-string keys with fmt.Sprint before inserting
- Audit custom store/plugin code that appends TreeItems
When it happens
Trigger: Calling sopsToGo (directly or via treeBranchToMetadata during ExtractMetadata) on a branch containing a TreeItem whose Key is, e.g., an int, bool, or custom type instead of string.
Common situations: Custom stores or plugins that insert numeric/typed keys into branches, programmatic tree manipulation (e.g. appending items with int keys), or code ported from other formats where keys aren't strings.
Related errors
AI-assisted analysis of getsops/sops@13442bb981 (2026-09-01).
Data as JSON: /api/errors/80f43399c927d7d4.
Report an issue: GitHub.