{"record":{"id":"c292e96cc7a25c1c","repo":"apache/answer","slug":"config-not-found-by-key-s","errorCode":null,"errorMessage":"config not found by key: %s","messagePattern":"config not found by key: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/repo/config/config_repo.go","lineNumber":92,"sourceCode":"\nfunc (cr configRepo) GetConfigByKey(ctx context.Context, key string) (c *entity.Config, err error) {\n\tcacheKey := constant.ConfigKEY2ContentCacheKeyPrefix + key\n\tcacheData, exist, err := cr.data.Cache.GetString(ctx, cacheKey)\n\tif err == nil && exist && len(cacheData) > 0 {\n\t\tc = &entity.Config{}\n\t\tc.BuildByJSON([]byte(cacheData))\n\t\tif c.ID > 0 {\n\t\t\treturn c, nil\n\t\t}\n\t}\n\n\tc = &entity.Config{Key: key}\n\texist, err = cr.data.DB.Context(ctx).Get(c)\n\tif err != nil {\n\t\treturn nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()\n\t}\n\tif !exist {\n\t\treturn nil, fmt.Errorf(\"config not found by key: %s\", key)\n\t}\n\n\t// update cache\n\tif err := cr.data.Cache.SetString(ctx, cacheKey, c.JsonString(), constant.ConfigCacheTime); err != nil {\n\t\tlog.Error(err)\n\t}\n\treturn c, nil\n}\n\nfunc (cr configRepo) GetConfigByKeyFromDB(ctx context.Context, key string) (c *entity.Config, err error) {\n\tc = &entity.Config{Key: key}\n\texist, err := cr.data.DB.Context(ctx).Get(c)\n\tif err != nil {\n\t\treturn nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()\n\t}\n\tif !exist {\n\t\treturn nil, fmt.Errorf(\"config not found by key: %s\", key)\n\t}","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/apache/answer/blob/3b9f1370612e690a0b7f230f05e688930db4c6d3/internal/repo/config/config_repo.go#L74-L110","documentation":"GetConfigByKey looks up a config row by its unique key using a zero-value entity as the query; when no row matches the key it returns this error. This is the key-based variant of the config lookup and is typically used by feature/config readers at startup or request time.","triggerScenarios":"Reading a config key that was never inserted into the config table, or a key misspelled/renamed in code but not in the database (or vice versa).","commonSituations":"New config key added in code without its seed/migration row; environment missing seed data; typos in the key constant; key renamed in an upgrade without a data migration.","solutions":["Compare the key constant in code with the config table (SELECT * FROM config WHERE config_key = '<key>';).","Add the missing row via migration/seed for every environment.","Search the codebase for the key constant to fix typos or renames.","Handle the error at the call site with a sensible default value for optional configs."],"exampleFix":"// before\nc = &entity.Config{Key: key}\nexist, err = cr.data.DB.Context(ctx).Get(c)\nif !exist {\n    return nil, fmt.Errorf(\"config not found by key: %s\", key)\n}\n// after\nc = &entity.Config{Key: key}\nexist, err = cr.data.DB.Context(ctx).Get(c)\nif err != nil {\n    return nil, err\n}\nif !exist {\n    return defaultValue, nil // fall back for optional keys\n}","handlingStrategy":"validation","validationCode":"var count int64\ndb.Model(&entity.Config{}).Where(\"config_key = ?\", key).Count(&count)\nif count == 0 {\n    return fmt.Errorf(\"config key %q is missing; add it via migration\", key)\n}","typeGuard":"func hasConfigKey(keys map[string]string, key string) bool {\n    _, ok := keys[key]\n    return ok\n}","tryCatchPattern":"val, err := configRepo.GetConfigByKey(ctx, key)\nif err != nil {\n    if strings.Contains(err.Error(), \"config not found by key\") {\n        val = defaultFor(key) // fall back for optional configs\n    } else {\n        return err\n    }\n}","preventionTips":["Add every new config key to seed data/migrations in the same PR that uses it.","Centralize keys as constants and grep for typos before release.","Provide sensible defaults for optional keys at call sites.","Diff config tables between environments when debugging."],"tags":["database","config","not-found"],"backgroundTag":"record-not-found","analyzedSha":"3b9f1370612e690a0b7f230f05e688930db4c6d3","analyzedAt":"2026-09-05T18:18:39.533Z","contentChangedAt":"2026-09-05T18:18:39.533Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}