twigphp/Twig · error · InvalidArgumentException
Locale " " is not supported.
Error message
Locale "%s" is not supported.
What it means
StringExtension::getInflector() maps a locale to a doctrine/inflector implementation (English, Spanish, French, ...). When the locale has no case in its switch, it throws an InvalidArgumentException. The plural/singular filters accept a locale argument, and only a fixed set of languages is supported.
Solutions
- Use a supported locale: 'en', 'es', 'fr' (check the extension's switch for the exact set).
- Normalize the locale to its primary subtag and default to 'en' when unsupported, e.g. explode('_', $locale)[0] with a fallback.
- For other languages, subclass StringExtension and override getInflector() to plug in your own doctrine/inflector rules.
Example fix
// before
{{ word|plural(app.request.locale) }} {# locale = "de_DE" #}
// after
{% set loc = app.request.locale|split('_')[0] %}
{{ word|plural(loc in ['en','es','fr'] ? loc : 'en') }} Defensive patterns
Strategy: validation
Validate before calling
$supported = ['en', 'es', 'fr'];
$loc = explode('_', $locale)[0];
if (!in_array($loc, $supported, true)) {
$loc = 'en'; // or skip the filter
} Try / catch
try {
$out = $twig->render($tpl, ['word' => $word, 'locale' => $loc]);
} catch (\InvalidArgumentException $e) {
// unsupported locale; fall back to default inflection
} Prevention
- Never pass raw BCP47/POSIX locale strings (de_DE, fr_FR.UTF-8) into plural/singular; normalize to the primary subtag first.
- Whitelist locales in application code before using inflection filters.
- If you need other languages, extend StringExtension and override getInflector() with custom doctrine/inflector rules.
When it happens
Trigger: Calling the plural or singular Twig filters with an unsupported locale argument, e.g. {{ 'cats'|plural('de') }} or {{ 'chats'|singular('it') }}, where 'de'/'it' are not handled by getInflector's switch.
Common situations: Passing the app's locale straight into the filter (apps commonly run de_DE, it_IT, pt_BR); locale strings like 'pt_BR' or with charset suffix 'fr_FR.UTF-8' that don't match bare case labels like 'fr'; assuming all ICU locales are supported.
Related errors
- A block chain requires at least one template.
- The "format_list" filter requires the "IntlListFormatter"…
- The date format " " does not exist, known formats are: " ".
- The time format " " does not exist, known formats are: " ".
- The style " " does not exist, known styles are: " ".
AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13).
Data as JSON: /api/errors/ea4b163a36e5a8d0.
Report an issue: GitHub.
Appendix: source
Thrown at extra/string-extra/StringExtension.php:96
return $this->getInflector($locale)->singularize($value)[0];
}
private function getInflector(string $locale): InflectorInterface
{
switch ($locale) {
case 'en':
return $this->englishInflector ?? $this->englishInflector = new EnglishInflector();
case 'es':
if (!class_exists(SpanishInflector::class)) {
throw new RuntimeError('SpanishInflector is not available.');
}
return $this->spanishInflector ?? $this->spanishInflector = new SpanishInflector();
case 'fr':
return $this->frenchInflector ?? $this->frenchInflector = new FrenchInflector();
default:
throw new \InvalidArgumentException(\sprintf('Locale "%s" is not supported.', $locale));
}
}
}
View on GitHub (pinned to a414c3a491)