twigphp/Twig · error · RuntimeError

Constant " " is undefined.

Error message

Constant "%s" is undefined.

What it means

CoreExtension::constant() throws this RuntimeError when Twig's `constant()` function is called with a constant name that is not defined via defined(), and the name is not the special `::class` case. This mirrors PHP's own "Undefined constant" error but as a Twig RuntimeError, so templates fail with a clear message instead of a PHP fatal Error.

Solutions

  1. Correct the constant name/namespace in the template to match the actual defined constant
  2. Verify with php -r 'var_dump(defined("FOO_BAR"));' or grep the class for the constant
  3. Guard in the template with `{% if constant('FOO_BAR') is defined %}`... wait — use `{{ FOO_BAR is defined ? constant('FOO_BAR') : default }}` pattern via defined checks where supported
  4. If the constant was removed upstream, replace it with the new name or inline the value

Example fix

// before (Twig template)
{{ constant('User::ROLE_ADMIN') }}
// after (constant lives on App\Entity\User and an object is in scope)
{{ constant('ROLE_ADMIN', user) }}
Defensive patterns

Strategy: validation

Validate before calling

// PHP, before rendering
if (!\defined('App\\Constants::ROLE_ADMIN')) {
    throw new \LogicException('Referenced constant no longer exists; update templates.');
}

Type guard

function constantExists(string $name, ?object $object = null): bool
{
    return null !== $object
        ? ('class' === $name || \defined($object::class.'::'.$name))
        : \defined($name);
}

Try / catch

try {
    $value = \Twig\Extension\CoreExtension::constant($name, $object);
} catch (\Twig\Error\RuntimeError $e) {
    if (!str_starts_with($e->getMessage(), 'Constant "') ) { throw $e; }
    $value = $default;
}

Prevention

When it happens

Trigger: `{{ constant('FOO_BAR') }}` when FOO_BAR is not defined; `{{ constant('MISSING', object) }}` when the object's class lacks that constant; typos in constant names; constants removed from a dependency after a version upgrade; referencing constants with wrong casing/namespace in the template string.

Common situations: Upgrading a library that removed or renamed a class constant while templates still reference it; typo in the constant name inside the template; the constant exists only in a different namespace than the string passed; constants that only exist in dev/test environments.

Understand the failure class

Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.

Related errors


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

Appendix: source

Thrown at src/Extension/CoreExtension.php:1695

    {
        if (null !== $object) {
            if ('class' === $constant) {
                return $checkDefined ? true : $object::class;
            }

            $constant = $object::class.'::'.$constant;
        }

        if (!\defined($constant)) {
            if ($checkDefined) {
                return false;
            }

            if ('::class' === strtolower(substr($constant, -7))) {
                throw new RuntimeError(\sprintf('You cannot use the Twig function "constant" to access "%s". You could provide an object and call constant("class", $object) or use the class name directly as a string.', $constant));
            }

            throw new RuntimeError(\sprintf('Constant "%s" is undefined.', $constant));
        }

        return $checkDefined ? true : \constant($constant);
    }

    /**
     * Batches item.
     *
     * @param array $items An array of items
     * @param int   $size  The size of the batch
     * @param mixed $fill  A value used to fill missing items
     *
     * @internal
     */
    public static function batch($items, $size, $fill = null, $preserveKeys = true): array
    {
        if (!is_iterable($items)) {
            throw new RuntimeError(\sprintf('The "batch" filter expects a sequence or a mapping, got "%s".', get_debug_type($items)));

View on GitHub (pinned to a414c3a491)