apache/answer · error
config not found by key: %s
Error message
config not found by key: %s
What it means
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.
Source
Thrown at internal/repo/config/config_repo.go:92
func (cr configRepo) GetConfigByKey(ctx context.Context, key string) (c *entity.Config, err error) {
cacheKey := constant.ConfigKEY2ContentCacheKeyPrefix + key
cacheData, exist, err := cr.data.Cache.GetString(ctx, cacheKey)
if err == nil && exist && len(cacheData) > 0 {
c = &entity.Config{}
c.BuildByJSON([]byte(cacheData))
if c.ID > 0 {
return c, nil
}
}
c = &entity.Config{Key: key}
exist, err = cr.data.DB.Context(ctx).Get(c)
if err != nil {
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
if !exist {
return nil, fmt.Errorf("config not found by key: %s", key)
}
// update cache
if err := cr.data.Cache.SetString(ctx, cacheKey, c.JsonString(), constant.ConfigCacheTime); err != nil {
log.Error(err)
}
return c, nil
}
func (cr configRepo) GetConfigByKeyFromDB(ctx context.Context, key string) (c *entity.Config, err error) {
c = &entity.Config{Key: key}
exist, err := cr.data.DB.Context(ctx).Get(c)
if err != nil {
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
if !exist {
return nil, fmt.Errorf("config not found by key: %s", key)
}View on GitHub (pinned to 3b9f137061)
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.
Example fix
// before
c = &entity.Config{Key: key}
exist, err = cr.data.DB.Context(ctx).Get(c)
if !exist {
return nil, fmt.Errorf("config not found by key: %s", key)
}
// after
c = &entity.Config{Key: key}
exist, err = cr.data.DB.Context(ctx).Get(c)
if err != nil {
return nil, err
}
if !exist {
return defaultValue, nil // fall back for optional keys
} Defensive patterns
Strategy: validation
Validate before calling
var count int64
db.Model(&entity.Config{}).Where("config_key = ?", key).Count(&count)
if count == 0 {
return fmt.Errorf("config key %q is missing; add it via migration", key)
} Type guard
func hasConfigKey(keys map[string]string, key string) bool {
_, ok := keys[key]
return ok
} Try / catch
val, err := configRepo.GetConfigByKey(ctx, key)
if err != nil {
if strings.Contains(err.Error(), "config not found by key") {
val = defaultFor(key) // fall back for optional configs
} else {
return err
}
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- config not found by id: %d
- get config failed: %w
- connect database failed: %w
- get config failed: %w
- %s activity not exist
AI-assisted analysis of apache/answer@3b9f137061 (2026-09-05).
Data as JSON: /api/errors/c292e96cc7a25c1c.
Report an issue: GitHub.