{"record":{"id":"50e391784e936fd4","repo":"AlexxIT/go2rtc","slug":"credentials-storage-not-initialized","errorCode":null,"errorMessage":"credentials: storage not initialized","messagePattern":"credentials: storage not initialized","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/creds/creds.go","lineNumber":24,"sourceCode":"\t\"path/filepath\"\n\t\"regexp\"\n\t\"strings\"\n)\n\ntype Storage interface {\n\tSetValue(name, value string) error\n\tGetValue(name string) (string, bool)\n}\n\nvar storage Storage\n\nfunc SetStorage(s Storage) {\n\tstorage = s\n}\n\nfunc SetValue(name, value string) error {\n\tif storage == nil {\n\t\treturn errors.New(\"credentials: storage not initialized\")\n\t}\n\tif err := storage.SetValue(name, value); err != nil {\n\t\treturn err\n\t}\n\tAddSecret(value)\n\treturn nil\n}\n\nfunc GetValue(name string) (value string, ok bool) {\n\tvalue, ok = getValue(name)\n\tAddSecret(value)\n\treturn\n}\n\nfunc getValue(name string) (string, bool) {\n\tif storage != nil {\n\t\tif value, ok := storage.GetValue(name); ok {\n\t\t\treturn value, true","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/creds/creds.go#L6-L42","documentation":"pkg/creds/creds.go:24 backs the credential store with a package-level storage set via SetStorage. SetValue checks that storage first; if SetStorage was never called (storage == nil) it returns \"credentials: storage not initialized\". The library deliberately fails fast instead of silently dropping credentials — there is nowhere to persist the value.","triggerScenarios":"Calling creds.SetValue (directly or via anything that stores credentials) in a process where creds.SetStorage(s) was never invoked — e.g. a service that uses this library without wiring a credentials backend (file, database, etc.).","commonSituations":"Embedding the library in a custom binary while forgetting to initialize the creds backend at startup; running components (tests, CLI tools) that skip the storage setup step; ordering bug where SetValue runs before SetStorage during init.","solutions":["Call creds.SetStorage(impl) at startup before any SetValue, with a real Storage implementation.","If you don't need persistence, use the library's provided in-memory/file storage implementation rather than leaving storage nil.","Fix initialization order so SetStorage runs in main/init before workers call SetValue.","Wrap SetValue calls with a check/error message pointing to the missing SetStorage call."],"exampleFix":"// before\nfunc main() {\n    _ = creds.SetValue(\"camera_password\", \"secret\") // storage not initialized\n}\n// after\nfunc main() {\n    creds.SetStorage(NewFileStorage(\"/data/creds.json\"))\n    _ = creds.SetValue(\"camera_password\", \"secret\")\n}","handlingStrategy":"validation","validationCode":"if !credsInitialized { // set true right after SetStorage\n    return errors.New(\"call creds.SetStorage before using credentials\")\n}","typeGuard":null,"tryCatchPattern":"if err := creds.SetValue(name, value); err != nil && strings.Contains(err.Error(), \"storage not initialized\") {\n    return fmt.Errorf(\"credentials backend missing: %w (call creds.SetStorage at startup)\", err)\n}","preventionTips":["Call creds.SetStorage as the first step of main/init","Add a smoke test that SetValue works in your binary","Never delay storage setup behind lazy paths","Use the library's provided storage implementations"],"tags":["credentials","initialization","configuration"],"backgroundTag":"missing-configuration","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}