kataras/iris · error
<%s = %s>: %w
Error message
<%s = %s>: %w
What it means
i18n's setString registers a message key for a locale. When the value is plural (a PluralForm was given) it builds an independent plural renderer via newIndependentPluralRenderer; if that fails, the underlying go-i18n catalog/plural error is wrapped as "<key = value>: err". It means the plural rule or message syntax for this plural key could not be compiled/registered in the underlying catalog.
Source
Thrown at i18n/internal/locale.go:116
var (
renderer, pluralRenderer Renderer = m, m
)
if stringIsTemplateValue(value, loc.Options.Left, loc.Options.Right) {
t, err := NewTemplate(c, m)
if err != nil {
return err
}
pluralRenderer = t
if !isPlural {
renderer = t
}
} else {
if isPlural {
pluralRenderer, err = newIndependentPluralRenderer(c, loc, key, msgs...)
if err != nil {
return fmt.Errorf("<%s = %s>: %w", key, value, err)
}
} else if err = c.Set(loc.tag, key, msgs...); err != nil {
// let's make normal keys direct fire:
// renderer = &simpleRenderer{key, loc.Printer}
return fmt.Errorf("<%s = %s>: %w", key, value, err)
}
}
if isPlural {
if existingMsg, ok := loc.Messages[key]; ok {
if msg, ok := existingMsg.(*Message); ok {
msg.AddPlural(form, pluralRenderer)
return
}
}
m.AddPlural(form, pluralRenderer)View on GitHub (pinned to 7bedaf55a0)
Solutions
- Fix the plural message string syntax for the key shown in the error (check braces and plural cases).
- Verify the PluralForm used matches the locale's CLDR plural categories (one, other, few...).
- Check the wrapped inner error (%w) for the exact catalog/plural parse failure and address it.
- Set DefaultMessageFunc or test the key with a minimal message to isolate the failing syntax.
Example fix
// before
loc.Set("en-US", "dogs", "You have %d dog|one:dog|many:dogs", i18n.Plural("many"))
// after (valid CLDR form + syntax)
loc.Set("en-US", "dogs", "You have %d dog|one:dog|other:dogs", i18n.Plural("other")) Defensive patterns
Strategy: validation
Validate before calling
// validate plural message before Set
if strings.Contains(value, "|") && form == nil {
return fmt.Errorf("key %q: plural syntax used without a PluralForm", key)
}
// ensure value braces are balanced
if strings.Count(value, "{{") != strings.Count(value, "}}") {
return fmt.Errorf("key %q: unbalanced template braces", key)
} Try / catch
if err := loc.Set(tag, key, msgs...); err != nil {
var perr error
if errors.As(err, &perr) {
log.Printf("plural registration failed for %s: %v", key, perr)
}
return err
} Prevention
- Always register an "other" (fallback) plural form for every plural key.
- Keep plural message syntax consistent per language's CLDR categories.
- Run a startup test that Sets and Renders every key for every locale.
- Fail fast at load time instead of at request time.
When it happens
Trigger: Calling Set/Set plural variants (e.g. loc.Set with PluralForm) where newIndependentPluralRenderer returns an error — typically a malformed plural message string (invalid select/plural syntax) or an invalid plural form for the language tag.
Common situations: Translation files or inline messages with broken plural templates (e.g. mismatched braces in {{.Var}} or invalid plural cases), plural keys declared with forms the language's plural rules do not accept, or copy-pasted plural rules between languages with different CLDR categories.
Related errors
- key: %q: no registered plurals for <%d>
- key: %q: missing plural count argument
- nil loader
- catalog: empty languages
- expected language index to be lower or equal than %d but got
AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30).
Data as JSON: /api/errors/6d19f64586d87450.
Report an issue: GitHub.