{"id":"fa82535d1b3f2a24","repo":"spf13/viper","slug":"encoder-not-found-for-this-format","errorCode":null,"errorMessage":"encoder not found for this format","messagePattern":"encoder not found for this format","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"encoding.go","lineNumber":135,"sourceCode":"// Format is case-insensitive.\nfunc (r *DefaultCodecRegistry) RegisterCodec(format string, codec Codec) error {\n\tr.init()\n\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()\n\n\tr.codecs[strings.ToLower(format)] = codec\n\n\treturn nil\n}\n\n// Encoder implements the [EncoderRegistry] interface.\n//\n// Format is case-insensitive.\nfunc (r *DefaultCodecRegistry) Encoder(format string) (Encoder, error) {\n\tencoder, ok := r.codec(format)\n\tif !ok {\n\t\treturn nil, errors.New(\"encoder not found for this format\")\n\t}\n\n\treturn encoder, nil\n}\n\n// Decoder implements the [DecoderRegistry] interface.\n//\n// Format is case-insensitive.\nfunc (r *DefaultCodecRegistry) Decoder(format string) (Decoder, error) {\n\tdecoder, ok := r.codec(format)\n\tif !ok {\n\t\treturn nil, errors.New(\"decoder not found for this format\")\n\t}\n\n\treturn decoder, nil\n}\n\nfunc (r *DefaultCodecRegistry) codec(format string) (Codec, bool) {","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/spf13/viper/blob/528f7416c4b56a4948673984b190bf8713f0c3c4/encoding.go#L117-L153","documentation":"Returned by DefaultCodecRegistry.Encoder (encoding.go:132-138) when r.codec(format) finds no match. The built-in registry only ships codecs for yaml/yml, json, toml, and dotenv/env (encoding.go:166-178); any other format string yields this error. It surfaces through marshalWriter (viper.go:1818) whenever Viper serializes config to a file or io.Writer.","triggerScenarios":"Calling WriteConfig, WriteConfigAs, SafeWriteConfig, or WriteConfigTo when the resolved configType (filename extension or SetConfigType value) is one of the SupportedExts entries that has no built-in codec in this version — 'ini', 'hcl', 'tfvars', 'properties', 'props', 'prop' — or any custom/unregistered format string. marshalWriter calls v.encoderRegistry.Encoder(configType) and wraps the result in ConfigMarshalError.","commonSituations":"Upgrading from an older Viper that bundled HCL/INI/properties encoders; switching a YAML app to write .hcl/.ini; passing a custom registry via WithEncoderRegistry that forgot RegisterCodec for the format you write; typo in the file extension.","solutions":["Write to a format with a built-in codec: use an extension of json, yaml/yml, toml, or dotenv/env (SetConfigType or filename ext).","If you must write hcl/ini/properties/etc., construct a DefaultCodecRegistry, call RegisterCodec(\"hcl\", myCodec), and pass it via v := NewWithOptions(WithEncoderRegistry(r)) or WithCodecRegistry(r).","Verify the format is actually registered before writing: guard with slices.Contains([]string{\"json\",\"yaml\",\"yml\",\"toml\",\"env\",\"dotenv\"}, configType)."],"exampleFix":"// before\nv.SetConfigName(\"app\")\nv.SetConfigType(\"hcl\")\nv.AddConfigPath(\"/etc/myapp\")\n_ = v.WriteConfig() // -> ConfigMarshalError: encoder not found for this format\n\n// after (option A: use built-in codec)\nv.SetConfigType(\"yaml\")\n_ = v.WriteConfig()\n\n// after (option B: register an HCL codec)\nr := NewCodecRegistry()\n_ = r.RegisterCodec(\"hcl\", myHCLCodec{})\nv := NewWithOptions(WithCodecRegistry(r))","handlingStrategy":"validation","validationCode":"// Confirm a built-in codec exists before writing.\nvar hasBuiltinEncoder = map[string]bool{\"json\": true, \"yaml\": true, \"yml\": true, \"toml\": true, \"env\": true, \"dotenv\": true}\nfunc canEncode(format string) bool { return hasBuiltinEncoder[strings.ToLower(format)] }\n\n// usage\ncfgType := strings.ToLower(v.GetConfigType())\nif cfgType == \"\" { cfgType = strings.TrimPrefix(filepath.Ext(outPath), \".\") }\nif !canEncode(cfgType) {\n    // register a codec via NewCodecRegistry().RegisterCodec(cfgType, codec), or switch extension\n}","typeGuard":null,"tryCatchPattern":"if err := v.WriteConfig(); err != nil {\n    var marshalErr viper.ConfigMarshalError\n    if errors.As(err, &marshalErr) {\n        // encoder missing -> register a codec or change format\n    }\n}","preventionTips":["Treat SupportedExts as 'recognized extensions', not 'formats with codecs'; only json/yaml/yml/toml/env/dotenv ship encoders.","Pin codec availability in a unit test that calls WriteConfig for every format your app writes.","When introducing a custom format, register its codec once at process start via WithCodecRegistry."],"tags":["encoding","codec","config-write","registry"],"analyzedSha":"528f7416c4b56a4948673984b190bf8713f0c3c4","analyzedAt":"2026-08-04T21:46:12.352Z","schemaVersion":2}