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

  1. Compare the key constant in code with the config table (SELECT * FROM config WHERE config_key = '<key>';).
  2. Add the missing row via migration/seed for every environment.
  3. Search the codebase for the key constant to fix typos or renames.
  4. 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

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


AI-assisted analysis of apache/answer@3b9f137061 (2026-09-05). Data as JSON: /api/errors/c292e96cc7a25c1c. Report an issue: GitHub.