twigphp/Twig · error · Twig\Error\RuntimeError

The "format_list" filter requires the "IntlListFormatter"…

Error message

The "format_list" filter requires the "IntlListFormatter" class, which is available since PHP 8.5.

What it means

The format_list filter of IntlExtension formats an array of strings into a locale-aware list (e.g. 'A, B and C'). It relies on PHP's IntlListFormatter class, which only exists in PHP 8.5+ with the intl extension. If the class is missing, the extension throws this RuntimeError instead of failing later inside IntlListFormatter.

Solutions

  1. Upgrade PHP to 8.5 or newer, since IntlListFormatter is only available since PHP 8.5
  2. Install/enable the intl extension (ext-intl) for your PHP version if 8.5+ is already running
  3. Guard usage with class_exists('IntlListFormatter') and fall back to manual joining (e.g. implode) until the runtime is updated
  4. Remove or branch around the format_list filter in templates that must run on older PHP

Example fix

// before
{{ items|format_list }}
// after
{% if class_exists('IntlListFormatter') %}
  {{ items|format_list }}
{% else %}
  {{ items|join(', ') }}
{% endif %}
Defensive patterns

Strategy: fallback

Validate before calling

if (!class_exists('IntlListFormatter')) { throw new \LogicException('format_list requires PHP 8.5+ with ext-intl; upgrade or use join().'); }

Type guard

function supportsFormatList(): bool { return \class_exists('IntlListFormatter'); }

Try / catch

try { $out = $twig->render($tpl, $ctx); } catch (\Twig\Error\RuntimeError $e) { if (str_contains($e->getMessage(), 'IntlListFormatter')) { $out = fallbackJoin($ctx); } else { throw $e; } }

Prevention

When it happens

Trigger: Calling the format_list Twig filter (IntlExtension::formatList) when the IntlListFormatter class does not exist — i.e. running PHP < 8.5, or PHP without the ext-intl extension compiled/loaded.

Common situations: Deploying an app using format_list to an older PHP runtime (pre-8.5); a container or shared host with ext-intl not installed; running unit tests on a PHP version matrix where intl is skipped.

Understand the failure class

Background: "X is not installed. Please install it with pip install Y": missing optional dependency errors — ImportError/ValueError raised when a library's optional extra was never installed — this error's family across 22 libraries.

Related errors


AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13). Data as JSON: /api/errors/36c39dca66cfa469. Report an issue: GitHub.

Appendix: source

Thrown at extra/intl-extra/IntlExtension.php:451

        return $this->formatDateTime($env, $date, $dateFormat, 'none', $pattern, $timezone, $calendar, $locale);
    }

    /**
     * @param \DateTimeInterface|string|null  $date     A date or null to use the current time
     * @param \DateTimeZone|string|false|null $timezone The target timezone, null to use the default, false to leave unchanged
     */
    public function formatTime(Environment $env, $date, ?string $timeFormat = null, string $pattern = '', $timezone = null, ?string $calendar = null, ?string $locale = null): string
    {
        return $this->formatDateTime($env, $date, 'none', $timeFormat, $pattern, $timezone, $calendar, $locale);
    }

    /**
     * @param array<string|\Stringable> $strings A list of items to be joined into a formatted list
     */
    public function formatList(array $strings, string $type = 'and', string $width = 'wide', ?string $locale = null): string
    {
        if (!class_exists('IntlListFormatter')) {
            throw new RuntimeError('The "format_list" filter requires the "IntlListFormatter" class, which is available since PHP 8.5.');
        }

        $formatter = $this->createListFormatter($locale, $type, $width);
        if (false === $ret = $formatter->format($strings)) {
            throw new RuntimeError(\sprintf('Unable to format the given list: %s', $formatter->getErrorMessage()));
        }

        return $ret;
    }

    private function createDateFormatter(?string $locale, ?string $dateFormat, ?string $timeFormat, string $pattern, ?\DateTimeZone $timezone, ?string $calendar): \IntlDateFormatter
    {
        $dateFormats = self::availableDateFormats();

        if (null !== $dateFormat && !isset($dateFormats[$dateFormat])) {
            throw new RuntimeError(\sprintf('The date format "%s" does not exist, known formats are: "%s".', $dateFormat, implode('", "', array_keys($dateFormats))));
        }

View on GitHub (pinned to a414c3a491)