{"id":"1cf13ac4b7d973d0","repo":"spf13/viper","slug":"cannot-decode-configuration-unable-to-determine-c","errorCode":null,"errorMessage":"cannot decode configuration: unable to determine config type","messagePattern":"cannot decode configuration: unable to determine config type","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"viper.go","lineNumber":1784,"sourceCode":"\t\tflags |= os.O_EXCL\n\t}\n\tf, err := v.fs.OpenFile(filename, flags, v.configPermissions)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer f.Close()\n\n\tif err := v.marshalWriter(f, configType); err != nil {\n\t\treturn err\n\t}\n\n\treturn f.Sync()\n}\n\nfunc (v *Viper) unmarshalReader(in io.Reader, c map[string]any) error {\n\tformat := strings.ToLower(v.getConfigType())\n\tif format == \"\" {\n\t\treturn errors.New(\"cannot decode configuration: unable to determine config type\")\n\t}\n\n\tbuf := new(bytes.Buffer)\n\t_, err := buf.ReadFrom(in)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to read configuration from input: %w\", err)\n\t}\n\n\t// TODO: remove this once SupportedExts is deprecated/removed\n\tif !slices.Contains(SupportedExts, format) {\n\t\treturn UnsupportedConfigError(format)\n\t}\n\n\t// TODO: return [UnsupportedConfigError] if the registry does not contain the format\n\t// TODO: consider deprecating this error type\n\tdecoder, err := v.decoderRegistry.Decoder(format)\n\tif err != nil {\n\t\treturn ConfigParseError{err}","sourceCodeStart":1766,"sourceCodeEnd":1802,"githubUrl":"https://github.com/spf13/viper/blob/528f7416c4b56a4948673984b190bf8713f0c3c4/viper.go#L1766-L1802","documentation":"Returned by unmarshalReader (viper.go:1781-1785) when getConfigType() returns \"\". getConfigType returns \"\" if v.configType is unset and either getConfigFile errors (no file located) or the resolved filename has no extension (viper.go:2121-2137). Without a format, Viper cannot pick a decoder.","triggerScenarios":"Calling v.ReadConfig(reader) or v.ReadConfigAs(reader) without first calling v.SetConfigType(...). Also when WatchConfig fires on a Viper instance whose config file has no recognized extension and SetConfigType was never called, or when reading remote/env config with no type set.","commonSituations":"Reading config from an io.Reader (string, bytes, env blob, remote KV) where there is no filename to infer the type from; refactoring that removed the SetConfigType call; reading a file literally named 'config' with no extension.","solutions":["Call v.SetConfigType(\"yaml\") (or json/toml/env) before v.ReadConfig(reader).","If reading from disk, ensure SetConfigName + AddConfigPath resolve a file with a recognized extension so getConfigType can infer it.","For remote providers, call SetConfigType after AddRemoteProvider."],"exampleFix":"// before\nv := New()\n_ = v.ReadConfig(strings.NewReader(`{\"port\": 8080}`)) // -> cannot decode configuration: unable to determine config type\n\n// after\nv := New()\nv.SetConfigType(\"json\")\n_ = v.ReadConfig(strings.NewReader(`{\"port\": 8080}`))","handlingStrategy":"validation","validationCode":"// getConfigType() is unexported; mirror its logic to validate before reading.\nfunc hasConfigType(v *viper.Viper, readerOnly bool) bool {\n    if v.GetConfigType() != \"\" { return true }\n    if readerOnly { return false } // no filename to infer from\n    // rely on SetConfigName + AddConfigPath resolving an extensioned file\n    return false\n}\n\n// before ReadConfig(reader):\nif v.GetConfigType() == \"\" {\n    v.SetConfigType(\"yaml\") // or json/toml/env\n}\nv.ReadConfig(reader)","typeGuard":null,"tryCatchPattern":"if err := v.ReadConfig(r); err != nil {\n    if strings.Contains(err.Error(), \"unable to determine config type\") {\n        v.SetConfigType(\"yaml\")\n        err = v.ReadConfig(r)\n    }\n}","preventionTips":["Always pair ReadConfig/ReadConfigAs with an explicit SetConfigType.","For remote/env/reader sources where no filename exists, treat SetConfigType as mandatory.","Wrap Viper setup in a helper that refuses to return a Viper with empty config type for reader-based apps."],"tags":["config-read","setup","type","decoder"],"analyzedSha":"528f7416c4b56a4948673984b190bf8713f0c3c4","analyzedAt":"2026-08-04T21:46:12.352Z","schemaVersion":2}