{"record":{"id":"2abb6897687a48c9","repo":"go-kratos/kratos","slug":"key-not-found","errorCode":null,"errorMessage":"key not found","messagePattern":"key not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/config.go","lineNumber":20,"sourceCode":"\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"reflect\"\n\t\"sync\"\n\t\"time\"\n\n\t// init encoding\n\t_ \"github.com/go-kratos/kratos/v3/encoding/json\"\n\t_ \"github.com/go-kratos/kratos/v3/encoding/proto\"\n\t_ \"github.com/go-kratos/kratos/v3/encoding/xml\"\n\t_ \"github.com/go-kratos/kratos/v3/encoding/yaml\"\n\t\"github.com/go-kratos/kratos/v3/log\"\n)\n\nvar _ Config = (*config)(nil)\n\nvar ErrNotFound = errors.New(\"key not found\") // ErrNotFound is key not found.\n\n// Observer is config observer.\ntype Observer func(string, Value)\n\n// Config is a config interface.\ntype Config interface {\n\tLoad() error\n\tScan(v any) error\n\tValue(key string) Value\n\tWatch(key string, o Observer) error\n\tClose() error\n}\n\ntype config struct {\n\topts      options\n\treader    Reader\n\tcached    sync.Map\n\tobservers sync.Map","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/go-kratos/kratos/blob/668db92c2c001e9552594ba5a8aede8456af6d7e/config/config.go#L2-L38","documentation":"Sentinel error from the kratos config package (config/config.go:20). It is returned in three places: Config.Value(key) wraps it in an errValue (surfaced when you call Bool()/Int()/String()/Load() on the returned Value), Config.Watch returns it directly when the key has no value, and the generic config.Get[T] returns it when v.Load() is nil. It means the requested key does not exist in any loaded and merged config source.","triggerScenarios":"cfg.Value(\"data.database.dsn\").String() when no source contains that dotted path; cfg.Watch(\"missing.key\", observer) before the key exists; config.Get[string](cfg, \"missing.key\"). Note Value() itself never errors - the error appears on the subsequent accessor call.","commonSituations":"Key path typo or wrong case (config keys are case-sensitive); dotted path not matching the actual YAML/JSON nesting; cfg.Load() failed earlier and the error was ignored so no source was merged; the config file was added but the app reads it before Load; environment-specific file missing so the key only exists in some deployments.","solutions":["Check that cfg.Load() was called and returned nil before any Value()/Watch()/Get call","Verify the exact key path against the loaded file, remembering nested YAML becomes dotted paths and keys are case-sensitive","Add the missing key to the source, or layer a file/env source that provides it","Detect the case explicitly with errors.Is(err, config.ErrNotFound) and supply a programmatic default"],"exampleFix":"// before\nv := cfg.Value(\"data.database.dsn\")\ndsn := v.String() // panics/errors with key not found at accessor time\n\n// after\nif err := cfg.Load(); err != nil { log.Fatal(err) }\ndsn, err := config.Get[string](cfg, \"data.database.dsn\")\nif errors.Is(err, config.ErrNotFound) {\n    dsn = \"root:root@tcp(127.0.0.1:3306)/app\" // explicit default\n}","handlingStrategy":"try-catch","validationCode":"func keyExists(cfg config.Config, key string) bool {\n    return cfg.Value(key).Load() != nil\n}\n\n// use before Watch:\nif !keyExists(cfg, \"data.database.dsn\") { /* add default source first */ }","typeGuard":null,"tryCatchPattern":"dsn, err := config.Get[string](cfg, \"data.database.dsn\")\nif err != nil {\n    if errors.Is(err, config.ErrNotFound) {\n        // missing key: apply default or fail with a clear startup message\n        dsn = defaultDSN\n    } else {\n        return err\n    }\n}","preventionTips":["Always call and check cfg.Load() before any Value/Watch/Get","Fail fast at startup on required keys instead of tolerating nil","Keep a single source of truth for key names (constants) shared by writer and reader","Remember Value() defers the error to the accessor call - test with .Load() != nil"],"tags":["config","sentinel-error","key-lookup"],"backgroundTag":null,"analyzedSha":"668db92c2c001e9552594ba5a8aede8456af6d7e","analyzedAt":"2026-08-16T02:07:20.704Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}