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

  1. Fix the plural message string syntax for the key shown in the error (check braces and plural cases).
  2. Verify the PluralForm used matches the locale's CLDR plural categories (one, other, few...).
  3. Check the wrapped inner error (%w) for the exact catalog/plural parse failure and address it.
  4. 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

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


AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30). Data as JSON: /api/errors/6d19f64586d87450. Report an issue: GitHub.