{"record":{"id":"83fc5a3318d6c1d2","repo":"getsops/sops","slug":"found-v-entry-that-is-not-a-mapping","errorCode":null,"errorMessage":"Found %v entry that is not a mapping","messagePattern":"Found (.+?) entry that is not a mapping","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"stores/metadata.go","lineNumber":122,"sourceCode":"\n// ExtractMetadata extracts SOPS metadata from the supplied tree branches.\nfunc ExtractMetadata(branches sops.TreeBranches, opts MetadataOpts) (sops.TreeBranches, sops.Metadata, error) {\n\tvar metadataTree sops.TreeBranch\n\tif opts.Flatten != MetadataFlattenFull {\n\t\tfirst := true\n\t\tfor bi, branch := range branches {\n\t\t\ti := 0\n\t\t\tfor i < len(branch) {\n\t\t\t\tif branch[i].Key == SopsMetadataKey {\n\t\t\t\t\tif bi == 0 {\n\t\t\t\t\t\tif !first {\n\t\t\t\t\t\t\treturn nil, sops.Metadata{}, fmt.Errorf(\"Found duplicate %v entry\", SopsMetadataKey)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfirst = false\n\t\t\t\t\t\tif tree, ok := branch[i].Value.(sops.TreeBranch); ok {\n\t\t\t\t\t\t\tmetadataTree = tree\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn nil, sops.Metadata{}, fmt.Errorf(\"Found %v entry that is not a mapping\", SopsMetadataKey)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbranch = append(branch[:i], branch[i+1:]...)\n\t\t\t\t} else {\n\t\t\t\t\ti++\n\t\t\t\t}\n\t\t\t}\n\t\t\tbranches[bi] = branch\n\t\t}\n\t} else {\n\t\tif len(branches) >= 1 {\n\t\t\tbranch := branches[0]\n\t\t\tfor i := 0; i < len(branch); i++ {\n\t\t\t\tif key, ok := branch[i].Key.(string); ok {\n\t\t\t\t\tif strings.HasPrefix(key, SopsPrefix) {\n\t\t\t\t\t\tentry := branch[i]\n\t\t\t\t\t\tentry.Key = key[len(SopsPrefix):]\n\t\t\t\t\t\tmetadataTree = append(metadataTree, entry)","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/getsops/sops/blob/13442bb98183887d7a9ac09ec8ab0564673a59d8/stores/metadata.go#L104-L140","documentation":"Raised by ExtractMetadata when a `sops` key is found in the first branch but its value is not a nested mapping (sops.TreeBranch). The metadata block must be an object/map; a scalar or array value under the `sops` key cannot hold the metadata fields.","triggerScenarios":"Calling LoadEncryptedFile on a file where the `sops` key maps to a non-object value — e.g. `sops: ENC[...]`, `sops: true`, `sops: [1,2]` — typically from a data key legitimately named `sops` holding encrypted data instead of metadata, or a hand-mangled file.","commonSituations":"A user's real data uses the key `sops` and they created the file without proper metadata (unencrypted copy that includes a data key literally named sops), manual edits that replaced the metadata object, or a format-mismatch where a plain data file is fed through an encrypted-file loader.","solutions":["Rename the conflicting data key (anything other than `sops`) and re-encrypt","If the file is meant to be encrypted, re-create it with `sops -e` so a proper sops metadata mapping is embedded","If the file is plaintext, don't pass it to LoadEncryptedFile/decryption paths","Restore the original metadata object if the file was edited by hand"],"exampleFix":"// before: key 'sops' used for data\n{\"sops\": \"ENC[AES256_GCM,...]\"}\n// after: rename data key; 'sops' is reserved for metadata\n{\"my_sops_config\": \"ENC[AES256_GCM,...]\", \"sops\": {\"mac\": \"...\", ...}}","handlingStrategy":"validation","validationCode":"var probe struct {\n\tSops json.RawMessage `json:\"sops\"`\n}\nif err := json.Unmarshal(data, &probe); err == nil && len(probe.Sops) > 0 {\n\tvar obj map[string]interface{}\n\tif err := json.Unmarshal(probe.Sops, &obj); err != nil || obj == nil {\n\t\treturn errors.New(`\"sops\" key is present but not a JSON object`)\n\t}\n}","typeGuard":"func isTreeBranch(v interface{}) bool {\n\t_, ok := v.(sops.TreeBranch)\n\treturn ok\n}","tryCatchPattern":"tree, err := store.LoadEncryptedFile(data)\nif err != nil {\n\tif strings.Contains(err.Error(), \"entry that is not a mapping\") {\n\t\treturn fmt.Errorf(`the \"sops\" key must hold a metadata object: %w`, err)\n\t}\n\treturn err\n}","preventionTips":["Never use `sops` as a data key name in files you intend to encrypt","Create encrypted files only via `sops -e`, never by hand-adding a sops key","Only pass previously encrypted files to decryption/LoadEncryptedFile paths"],"tags":["metadata","structure","mapping","corruption"],"backgroundTag":"invalid-sops-metadata-structure","analyzedSha":"13442bb98183887d7a9ac09ec8ab0564673a59d8","analyzedAt":"2026-09-01T03:53:00.447Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}