kataras/iris · error

expected language index to be lower or equal than %d but got

Error message

expected language index to be lower or equal than %d but got %d

What it means

Catalog.Store writes a key/value translation map into the locale located by langIndex (index into c.Locales, i.e. the ordered languages given at construction). If langIndex is negative or >= len(Locales) there is no such locale and this error reports the allowed bound versus the given index.

Source

Thrown at i18n/internal/catalog.go:105

	}

	return c, nil
}

// Set sets a simple translation message.
func (c *Catalog) Set(tag language.Tag, key string, msgs ...catalog.Message) error {
	// fmt.Printf("Catalog.Set[%s] %s:\n", tag.String(), key)
	// for _, msg := range msgs {
	// 	fmt.Printf("%#+v\n", msg)
	// }
	return c.builder.Set(tag, key, msgs...)
}

// Store stores the a map of values to the locale derives from the given "langIndex".
func (c *Catalog) Store(langIndex int, kv Map) error {
	loc := c.getLocale(langIndex)
	if loc == nil {
		return fmt.Errorf("expected language index to be lower or equal than %d but got %d", len(c.Locales), langIndex)
	}
	return loc.Load(c, kv)
}

/* Localizer interface. */

// SetDefault changes the default language based on the "index".
// See `I18n#SetDefault` method for more.
func (c *Catalog) SetDefault(index int) bool {
	if index < 0 {
		index = 0
	}

	if maxIdx := len(c.Locales) - 1; index > maxIdx {
		return false
	}

	// callers should protect with mutex if called at serve-time.

View on GitHub (pinned to 7bedaf55a0)

Solutions

  1. Use langIndex values between 0 and len(catalog.Locales)-1
  2. Derive langIndex from the same ordered languages slice passed to NewCatalog, not from directory iteration order
  3. After adding a locale file, re-create the catalog with the languages list including it
  4. Look up the index via the catalog's language matching instead of hardcoding

Example fix

// before
for i := 0; i < len(files); i++ {
    c.Store(i, m) // files may exceed languages
}
// after
for i := range c.Locales {
    if err := c.Store(i, maps[i]); err != nil { return err }
}
Defensive patterns

Strategy: validation

Validate before calling

func idxOf(langs []language.Tag, want language.Tag) (int, error) {
    for i, l := range langs { if l == want { return i, nil } }
    return -1, fmt.Errorf("language %v not registered", want)
}

Type guard

func validIndex(i, n int) bool { return i >= 0 && i < n }

Try / catch

if err := c.Store(idx, kv); err != nil {
    if strings.Contains(err.Error(), "expected language index") {
        log.Printf("langIndex %d out of bounds (%d locales)", idx, len(c.Locales))
    }
    return err
}

Prevention

When it happens

Trigger: Calling catalog.Store(n, kv) (directly or via i18n loader wrappers) with an index outside 0..len(languages)-1 — e.g. iterating locales from a mismatched source list, or languages slice shrunk/changed after catalog creation.

Common situations: Loading translation files in arbitrary directory order while assuming sorted order matches the languages slice; adding a language to the folder but not to the languages list (or vice versa); off-by-one in index computation.

Related errors


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