{"record":{"id":"471f99e4356a644a","repo":"micro/go-micro","slug":"no-values","errorCode":null,"errorMessage":"no values","messagePattern":"no values","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/loader/memory/memory.go","lineNumber":322,"sourceCode":"\n\tch := m.snap.ChangeSet\n\n\t// we are truly screwed, trying to load in a hacked way\n\tv, err := m.opts.Reader.Values(ch)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// lets set it just because\n\tm.vals = v\n\n\tif m.vals != nil {\n\t\treturn m.vals.Get(path...)\n\t}\n\n\t// ok we're going hardcore now\n\n\treturn nil, errors.New(\"no values\")\n}\n\nfunc (m *memory) Load(sources ...source.Source) error {\n\tvar gerrors []string\n\n\tfor _, source := range sources {\n\t\tset, err := source.Read()\n\t\tif err != nil {\n\t\t\tgerrors = append(gerrors,\n\t\t\t\tfmt.Sprintf(\"error loading source %s: %v\",\n\t\t\t\t\tsource,\n\t\t\t\t\terr))\n\t\t\t// continue processing\n\t\t\tcontinue\n\t\t}\n\t\tm.Lock()\n\t\tm.sources = append(m.sources, source)\n\t\tm.sets = append(m.sets, set)","sourceCodeStart":304,"sourceCodeEnd":340,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/config/loader/memory/memory.go#L304-L340","documentation":"The in-memory config loader keeps loaded values in m.vals. Get normally delegates to m.vals.Get(path...), but if no values have ever been loaded (m.vals is nil) — typically because Load/Reload was never called or the loader was created with watch/options that skipped loading — it returns \"no values\". Watch calls Get first, so a disabled/unloaded loader also surfaces this error through Watch.","triggerScenarios":"Calling loader.Get(path...) (directly or via loader.Watch) on a memory loader instance before any successful Load/Reload populated it, or after construction with sources that all failed, leaving m.vals nil.","commonSituations":"Building config from sources whose Load failed earlier (errors were joined but the app continued); creating a memory loader programmatically without calling Load; unit tests that construct the loader and immediately query values.","solutions":["Call Load (or config.Load with your sources) and check its error before calling Get or Watch.","Inspect the joined error from Load — it aggregates per-source errors (including reload errors) — and fix the failing source.","In tests, seed the loader with an in-memory source and Load it before asserting on values.","If a value may legitimately be absent, use Get's error return to fall back to defaults instead of ignoring it."],"exampleFix":"// before\nv, _ := loader.Get(\"db\", \"host\")\n// after\nif err := loader.Load(source); err != nil {\n    log.Fatal(err)\n}\nv, err := loader.Get(\"db\", \"host\")\nif err != nil {\n    v = defaultHost\n}","handlingStrategy":"try-catch","validationCode":"if loader == nil {\n    return errors.New(\"loader not initialized\")\n}\nif err := loader.Load(sources...); err != nil {\n    return fmt.Errorf(\"loader has no values: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"v, err := loader.Get(\"db\", \"host\")\nif err != nil {\n    if err.Error() == \"no values\" {\n        v = defaultValue\n    } else {\n        return err\n    }\n}","preventionTips":["Always Load sources at startup and abort on error.","Never construct a memory loader in tests without seeding it via Load.","Provide defaults for critical keys so a failed load is visible but non-fatal where safe.","Check Load's joined error text for per-source failures."],"tags":["config","loader","go","uninitialized-state"],"backgroundTag":"config-not-loaded","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}