{"record":{"id":"20e78874b305748e","repo":"getsops/sops","slug":"value-to-encrypt-has-unsupported-type-t","errorCode":null,"errorMessage":"Value to encrypt has unsupported type %T","messagePattern":"Value to encrypt has unsupported type %T","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"aes/cipher.go","lineNumber":194,"sourceCode":"\tcase bool:\n\t\tencryptedType = \"bool\"\n\t\t// The Python version encodes booleans with Titlecase\n\t\tif value {\n\t\t\tplainBytes = []byte(\"True\")\n\t\t} else {\n\t\t\tplainBytes = []byte(\"False\")\n\t\t}\n\tcase time.Time:\n\t\tencryptedType = \"time\"\n\t\tplainBytes, err = value.MarshalText()\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"Error marshaling timestamp %q: %w\", value, err)\n\t\t}\n\tcase sops.Comment:\n\t\tencryptedType = \"comment\"\n\t\tplainBytes = []byte(value.Value)\n\tdefault:\n\t\treturn \"\", fmt.Errorf(\"Value to encrypt has unsupported type %T\", value)\n\t}\n\tout := gcm.Seal(nil, iv, plainBytes, []byte(additionalData))\n\treturn fmt.Sprintf(\"ENC[AES256_GCM,data:%s,iv:%s,tag:%s,type:%s]\",\n\t\tbase64.StdEncoding.EncodeToString(out[:len(out)-cryptoaes.BlockSize]),\n\t\tbase64.StdEncoding.EncodeToString(iv),\n\t\tbase64.StdEncoding.EncodeToString(out[len(out)-cryptoaes.BlockSize:]),\n\t\tencryptedType), nil\n}\n","sourceCodeStart":176,"sourceCodeEnd":203,"githubUrl":"https://github.com/getsops/sops/blob/13442bb98183887d7a9ac09ec8ab0564673a59d8/aes/cipher.go#L176-L203","documentation":"Encrypt supports a fixed set of plaintext Go types (string, int/float, bool, time.Time, sops.Comment). Any other Go type reaches the default branch of the type switch and is rejected with this error naming the actual %T type. It protects the format: unencodable values would silently corrupt the document.","triggerScenarios":"Passing a value of an unsupported type to Cipher.Encrypt — e.g. a map, slice, nil pointer, or custom struct inserted into a sops TreeBranch instead of a scalar.","commonSituations":"Programmatic use of the sops API where developers insert arbitrary Go objects into the tree; reflection-based tooling that forwards raw parsed YAML/JSON nodes (maps/slices) instead of leaves.","solutions":["Convert the value to a scalar (string, int, float, bool, time.Time) before encrypting.","For complex values, serialize to a string (YAML/JSON) and encrypt the string.","Add a case to the type switch in Encrypt if you fork and need a new supported type."],"exampleFix":"// before\ncipher.Encrypt(map[string]interface{}{\"a\": 1}, key, ad)\n// after\ncipher.Encrypt(fmt.Sprintf(\"a: 1\", ), key, ad) // or encrypt a scalar only","handlingStrategy":"type-guard","validationCode":"func encodable(v interface{}) bool {\n    switch v.(type) {\n    case string, int, int64, float64, bool, time.Time, sops.Comment:\n        return true\n    }\n    return false\n}","typeGuard":"if !encodable(value) {\n    value = fmt.Sprintf(\"%v\", value) // coerce to string first\n}","tryCatchPattern":"ciphertext, err := cipher.Encrypt(v, key, ad)\nif err != nil && strings.Contains(err.Error(), \"unsupported type\") {\n    return cipher.Encrypt(fmt.Sprintf(\"%v\", v), key, ad)\n}","preventionTips":["Insert only leaf scalars into sops TreeBranches","Serialize nested structures to YAML/JSON strings before encrypting","Add unit tests asserting tree values are encodable types"],"tags":["sops","aes","encryption","unsupported-type","type-switch"],"backgroundTag":"unsupported-plaintext-type","analyzedSha":"13442bb98183887d7a9ac09ec8ab0564673a59d8","analyzedAt":"2026-09-01T03:53:00.447Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}