{"record":{"id":"c8238ebb892665f8","repo":"symfony/translation","slug":"cannot-parse-message-translation-please-install-the-intl-php","errorCode":null,"errorMessage":"Cannot parse message translation: please install the \"intl\" PHP extension or the \"symfony/polyfill-intl-messageformatter\" package.","messagePattern":"Cannot parse message translation: please install the \"intl\" PHP extension or the \"symfony/polyfill-intl-messageformatter\" package\\.","errorType":"exception","errorClass":"LogicException","httpStatus":null,"severity":"error","filePath":"Formatter/IntlFormatter.php","lineNumber":35,"sourceCode":"/**\n * @author Guilherme Blanco <guilhermeblanco@hotmail.com>\n * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>\n */\nclass IntlFormatter implements IntlFormatterInterface\n{\n    private bool $hasMessageFormatter;\n    private array $cache = [];\n\n    public function formatIntl(string $message, string $locale, array $parameters = []): string\n    {\n        // MessageFormatter constructor throws an exception if the message is empty\n        if ('' === $message) {\n            return '';\n        }\n\n        if (!$formatter = $this->cache[$locale][$message] ?? null) {\n            if (!$this->hasMessageFormatter ??= class_exists(\\MessageFormatter::class)) {\n                throw new LogicException('Cannot parse message translation: please install the \"intl\" PHP extension or the \"symfony/polyfill-intl-messageformatter\" package.');\n            }\n            try {\n                $this->cache[$locale][$message] = $formatter = new \\MessageFormatter($locale, $message);\n            } catch (\\IntlException $e) {\n                throw new InvalidArgumentException(\\sprintf('Invalid message format (error #%d): ', intl_get_error_code()).intl_get_error_message(), 0, $e);\n            }\n        }\n\n        foreach ($parameters as $key => $value) {\n            if (\\in_array($key[0] ?? null, ['%', '{'], true)) {\n                unset($parameters[$key]);\n                $parameters[trim($key, '%{ }')] = $value;\n            }\n        }\n\n        if (false === $message = $formatter->format($parameters)) {\n            throw new InvalidArgumentException(\\sprintf('Unable to format message (error #%s): ', $formatter->getErrorCode()).$formatter->getErrorMessage());\n        }","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/symfony/translation/blob/ae9e8a51bc29780d63c7f9efd6005d7c875e100b/Formatter/IntlFormatter.php#L17-L53","documentation":"Thrown by IntlFormatter::formatIntl when the message uses ICU MessageFormat syntax but neither the intl PHP extension (MessageFormatter class) nor symfony/polyfill-intl-messageformatter is available. Without a MessageFormatter implementation, ICU-formatted messages cannot be parsed.","triggerScenarios":"Calling $translator->trans() (via MessageFormatter/IntlFormatter) on a message containing ICU syntax (e.g. '{count, plural, ...}') in a PHP build compiled without intl and without the polyfill installed.","commonSituations":"Deploying to a PHP environment (alpine/minimal Docker, some shared hosts) without ext-intl while local dev had it; production staging with different PHP images; translation files containing ICU plural/select messages.","solutions":["Install the intl PHP extension (`apk add php-intl` / `apt install php-intl` / enable extension=intl in php.ini)","Or run `composer require symfony/polyfill-intl-messageformatter` as a pure-PHP fallback","Align PHP extensions between dev and production images"],"exampleFix":"// before (Dockerfile)\nFROM php:8.2-fpm\n// after\nFROM php:8.2-fpm\nRUN docker-php-ext-install intl","handlingStrategy":"fallback","validationCode":"if (!class_exists(\\MessageFormatter::class) && !extension_loaded('intl')) { // install ext-intl or symfony/polyfill-intl-messageformatter before serving ICU messages }","typeGuard":"function intlMessageFormattingAvailable(): bool { return class_exists(\\MessageFormatter::class); }","tryCatchPattern":"try { $msg = $translator->trans($id, $params, $domain, $locale); } catch (LogicException $e) { if (str_contains($e->getMessage(), 'intl')) { $msg = $this->fallbackSimpleTrans($id, $params); } else { throw $e; } }","preventionTips":["Pin ext-intl in composer.json (`require ext-intl`) so composer install fails early","Use identical PHP base images for dev and production","Prefer the symfony/polyfill-intl-messageformatter package for portability"],"tags":["symfony","translation","intl","missing-dependency","icu"],"backgroundTag":"missing-optional-dependency","analyzedSha":"ae9e8a51bc29780d63c7f9efd6005d7c875e100b","analyzedAt":"2026-09-15T22:29:15.305Z","contentChangedAt":"2026-09-15T22:29:15.305Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}