twigphp/Twig · error · Twig\Error\RuntimeError

The style " " does not exist, known styles are: " ".

Error message

The style "%s" does not exist, known styles are: "%s".

What it means

createNumberFormatter validates the $style argument against the IntlExtension::NUMBER_STYLES constant before creating a \NumberFormatter. An unknown style name throws this RuntimeError listing the valid styles.

Solutions

  1. Use only styles listed in the error message / NUMBER_STYLES keys (decimal, currency, percent, scientific, spellout, ordinal, duration, etc.)
  2. Fix the style string in the template or PHP call
  3. Validate dynamic style values against IntlExtension NUMBER_STYLES keys before passing
  4. Fall back to 'decimal' when the configured style is unknown

Example fix

// before
{{ 12345.67|format_number(style='numerical') }}
// after
{{ 12345.67|format_number(style='decimal') }}
Defensive patterns

Strategy: validation

Validate before calling

if (!isset(IntlExtension::NUMBER_STYLES[$style])) { throw new \InvalidArgumentException("Unknown number style $style"); }

Type guard

function isKnownNumberStyle(string $s): bool { return isset(IntlExtension::NUMBER_STYLES[$s]); }

Try / catch

try { $out = $intl->formatNumber($n, $style); } catch (\Twig\Error\RuntimeError $e) { if (str_contains($e->getMessage(), 'style')) { $out = $intl->formatNumber($n, 'decimal'); } else { throw $e; } }

Prevention

When it happens

Trigger: Calling the format_number or format_currency filters with a style argument not in NUMBER_STYLES — e.g. 'integer', 'percent2', or a misspelled ' Spellout'.

Common situations: Typos in template filter arguments; using raw \NumberFormatter constant names (DECIMAL, SPELLOUT) in lowercase/incorrect string form; dynamic style values from config not validated beforehand.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

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

        }

        $timezoneName = $timezone ? $timezone->getName() : '(none)';
        $hash = $locale.'|'.$dateFormatValue.'|'.$timeFormatValue.'|'.$timezoneName.'|'.$calendar.'|'.$pattern;

        if (!isset($this->dateFormatters[$hash])) {
            if (\count($this->dateFormatters) >= self::MAX_CACHED_FORMATTERS) {
                array_shift($this->dateFormatters);
            }
            $this->dateFormatters[$hash] = new \IntlDateFormatter($locale, $dateFormatValue, $timeFormatValue, $timezone, $calendar, $pattern);
        }

        return $this->dateFormatters[$hash];
    }

    private function createNumberFormatter(?string $locale, string $style, array $attrs = []): \NumberFormatter
    {
        if (!isset(self::NUMBER_STYLES[$style])) {
            throw new RuntimeError(\sprintf('The style "%s" does not exist, known styles are: "%s".', $style, implode('", "', array_keys(self::NUMBER_STYLES))));
        }

        if (null === $locale) {
            $locale = \Locale::getDefault();
        }

        // textAttrs and symbols can only be set on the prototype as there is probably no
        // use case for setting it on each call.
        $textAttrs = [];
        $symbols = [];
        if ($this->numberFormatterPrototype) {
            foreach (self::NUMBER_ATTRIBUTES as $name => $const) {
                if (!isset($attrs[$name])) {
                    $value = $this->numberFormatterPrototype->getAttribute($const);
                    if ('rounding_mode' === $name) {
                        $value = array_flip(self::NUMBER_ROUNDING_ATTRIBUTES)[$value];
                    } elseif ('padding_position' === $name) {
                        $value = array_flip(self::NUMBER_PADDING_ATTRIBUTES)[$value];

View on GitHub (pinned to a414c3a491)