doctrine/inflector · error · InvalidArgumentException

Language "%s" is not supported.

Error message

Language "%s" is not supported.

What it means

InflectorFactory::createForLanguage() (src/InflectorFactory.php:26) accepts only the exact lowercase constants defined in Doctrine\Inflector\Language: 'english', 'esperanto', 'french', 'italian', 'norwegian-bokmal', 'portuguese', 'spanish', 'turkish'. Any other string falls through the switch to the default arm and throws InvalidArgumentException (src/InflectorFactory.php:53). The error is a strict allow-list mismatch: different casing, locale codes, and unsupported languages are all rejected.

Source

Thrown at src/InflectorFactory.php:54

                return new French\InflectorFactory();

            case Language::ITALIAN:
                return new Italian\InflectorFactory();

            case Language::NORWEGIAN_BOKMAL:
                return new NorwegianBokmal\InflectorFactory();

            case Language::PORTUGUESE:
                return new Portuguese\InflectorFactory();

            case Language::SPANISH:
                return new Spanish\InflectorFactory();

            case Language::TURKISH:
                return new Turkish\InflectorFactory();

            default:
                throw new InvalidArgumentException(sprintf(
                    'Language "%s" is not supported.',
                    $language
                ));
        }
    }
}

View on GitHub (pinned to 288d99b85c)

Solutions

  1. Pass a Language constant instead of a literal string: InflectorFactory::createForLanguage(Language::ENGLISH).
  2. If the value is dynamic, map it explicitly before the call: 'en' => Language::ENGLISH, 'pt'/'pt-BR' => Language::PORTUGUESE, 'nb' => Language::NORWEGIAN_BOKMAL, and so on.
  3. Whitelist the eight supported constants and validate the setting at boot so a bad value fails fast with a clear configuration error.
  4. If the requested language has no rules package, decide deliberately: fall back to InflectorFactory::create() (English) or reject the request — never forward the raw string.

Example fix

// before
$inflector = InflectorFactory::createForLanguage('EN')->build(); // throws InvalidArgumentException

// after
use Doctrine\Inflector\Language;

$inflector = InflectorFactory::createForLanguage(Language::ENGLISH)->build();
Defensive patterns

Strategy: validation

Validate before calling

use Doctrine\Inflector\InflectorFactory;
use Doctrine\Inflector\Language;
use InvalidArgumentException;

$supported = [
    Language::ENGLISH,
    Language::ESPERANTO,
    Language::FRENCH,
    Language::ITALIAN,
    Language::NORWEGIAN_BOKMAL,
    Language::PORTUGUESE,
    Language::SPANISH,
    Language::TURKISH,
];

$language = strtolower(trim($configLanguage));

if (! in_array($language, $supported, true)) {
    throw new InvalidArgumentException('Unsupported inflector language: ' . $configLanguage);
}

$inflector = InflectorFactory::createForLanguage($language)->build();

Type guard

use Doctrine\Inflector\Language;

function isSupportedInflectorLanguage(string $language): bool
{
    static $supported = [
        Language::ENGLISH,
        Language::ESPERANTO,
        Language::FRENCH,
        Language::ITALIAN,
        Language::NORWEGIAN_BOKMAL,
        Language::PORTUGUESE,
        Language::SPANISH,
        Language::TURKISH,
    ];

    return in_array($language, $supported, true);
}

Try / catch

use Doctrine\Inflector\InflectorFactory;
use InvalidArgumentException;

try {
    $inflector = InflectorFactory::createForLanguage($language)->build();
} catch (InvalidArgumentException $e) {
    // deliberate fallback: English rules instead of a hard failure
    $inflector = InflectorFactory::create()->build();
}

Prevention

When it happens

Trigger: Calling InflectorFactory::createForLanguage($language) with a string that is not byte-for-byte a Language constant: 'English' (wrong case), 'en' or 'en_US' (locale code, not a language name), 'norwegian' (the constant is 'norwegian-bokmal'), 'german'/'russian' (no rules package shipped), or a raw value from .env/YAML/API input passed through without mapping.

Common situations: Language configured via .env or a framework bundle where the developer assumed IETF locale codes ('en', 'pt-BR') work; user-facing APIs that accept a language parameter and forward it verbatim; typos and casing mismatches in hand-written config; migrations from doctrine/inflector 1.x where language handling differed. Usually fails on first call at runtime rather than at configuration load, which is why it surprises people.

Related errors


AI-assisted analysis of doctrine/inflector@288d99b85c (2026-08-21). Data as JSON: /api/errors/790ab1768adcf570. Report an issue: GitHub.