{"record":{"id":"af83cbaf65d0c124","repo":"getsops/sops","slug":"error-while-unflattening-w","errorCode":null,"errorMessage":"Error while unflattening: %w","messagePattern":"Error while unflattening: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"stores/flatten.go","lineNumber":194,"sourceCode":"func unflattenTreeBranch(branch sops.TreeBranch) (sops.TreeBranch, error) {\n\troot := &node{}\n\tfor _, item := range branch {\n\t\tif _, ok := item.Key.(sops.Comment); ok {\n\t\t\tcontinue\n\t\t}\n\t\tif key, ok := item.Key.(string); ok {\n\t\t\ttokens := tokenize(key)\n\t\t\terr := place(&item.Value, tokens, root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"Error while unflattening %q: %w\", key, err)\n\t\t\t}\n\t\t} else {\n\t\t\treturn nil, fmt.Errorf(\"Found non-string key %q when unflattening\", item.Key)\n\t\t}\n\t}\n\tresult, err := convert(root)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"Error while unflattening: %w\", err)\n\t}\n\tif tb, ok := result.(sops.TreeBranch); ok {\n\t\treturn tb, nil\n\t}\n\treturn nil, fmt.Errorf(\"Internal error: cannot find root\")\n}\n\n////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n// Flatten\n\nfunc flattenDescendValue(value interface{}, key string, destination sops.TreeBranch, destinationMap *map[string]bool) (sops.TreeBranch, error) {\n\tswitch value := value.(type) {\n\tcase sops.TreeBranch:\n\t\treturn flattenDescendMap(value, key+mapSeparator, destination, destinationMap)\n\tcase []interface{}:\n\t\treturn flattenDescendArray(value, key+listSeparator, destination, destinationMap)\n\t}\n\tif _, ok := (*destinationMap)[key]; ok {","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/getsops/sops/blob/13442bb98183887d7a9ac09ec8ab0564673a59d8/stores/flatten.go#L176-L212","documentation":"After tokenizing and placing all flattened keys into a node tree, unflattenTreeBranch calls convert(root) to rebuild the nested structure. convert fails with \"Duplicate value\", \"Type mismatch\", or \"Incomplete list\", and this wrapper re-raises it. It means the flattened key set does not correspond to a single consistent nested tree.","triggerScenarios":"Calling ExtractMetadata/unflattenTreeBranch with branches whose flattened keys collide semantically: e.g. both \"a\" and \"a__map_b\" set as leaf values (value + subkey = Type mismatch), the same leaf path supplied twice (Duplicate value), or a list with missing indices like __list_0 and __list_2 without __list_1 (Incomplete list).","commonSituations":"A manually edited encrypted file where the sops metadata section was mangled; a diff/merge that dropped one element of a list so indices are no longer contiguous; a script that wrote keys with inconsistent separator usage (__map_ vs plain dot); partial round-trip through another format that lost keys.","solutions":["Read the wrapped inner error (Duplicate value / Type mismatch / Incomplete list) and fix the offending key(s) it points to","Ensure lists use contiguous 0-based indices with no gaps","Do not set both a leaf value and child keys at the same path — pick one","Regenerate the flattened keys with stores Flatten rather than hand-crafting them"],"exampleFix":"// before: keys \"a__list_0\" and \"a__list_2\" exist (gap -> Incomplete list)\n// after: keys \"a__list_0\", \"a__list_1\", \"a__list_2\" (contiguous)","handlingStrategy":"validation","validationCode":"seen := map[string]bool{}\nfor _, item := range branch {\n\tif seen[item.Key.(string)] {\n\t\treturn fmt.Errorf(\"duplicate flattened key %q\", item.Key)\n\t}\n\tseen[item.Key.(string)] = true\n}","typeGuard":null,"tryCatchPattern":"tb, err := unflattenTreeBranch(branch)\nif err != nil {\n\tvar inner string\n\tif errors.Unwrap(err) != nil {\n\t\tinner = errors.Unwrap(err).Error()\n\t}\n\tlog.Printf(\"unflatten failed: %v (inner: %s)\", err, inner)\n\treturn err\n}","preventionTips":["Generate flattened keys with the Flatten functions, never by hand","Keep list indices contiguous starting at 0","Never place both a leaf value and children at the same path","Validate after merges/diffs before decrypting"],"tags":["go","sops","flatten","malformed-input"],"backgroundTag":"malformed-flattened-key","analyzedSha":"13442bb98183887d7a9ac09ec8ab0564673a59d8","analyzedAt":"2026-09-01T03:53:00.447Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}