twigphp/Twig · error · RuntimeError

Variable does not exist.

Error message

Variable %s does not exist.

What it means

This RuntimeError is thrown at runtime when a template accesses an undefined variable. Twig compiles variable reads into a check that the name exists in $context; if not, the generated closure raises this error with the template line and source.

Solutions

  1. Add the missing key to the context array passed to render()
  2. Fix the variable name typo in the template
  3. Provide a default: {{ foo|default('') }} or {% if foo is defined %}
  4. Enable Twig strict_variables explicitly during development to catch these early

Example fix

// before
return $twig->render('user.html', ['name' => $name]); // template uses {{ email }}
// after
return $twig->render('user.html', ['name' => $name, 'email' => $email]);
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify required context keys before rendering
$required = ['user', 'email'];
$missing = array_diff($required, array_keys($context));
if ($missing) {
    throw new InvalidArgumentException('Missing context keys: '.implode(',', $missing));
}

Type guard

// Template-level guard
// {% if email is defined %}{{ email }}{% endif %}

Try / catch

try {
    return $twig->render($template, $context);
} catch (\Twig\Error\RuntimeError $e) {
    if (str_contains($e->getMessage(), 'does not exist')) {
        // log template + line, fix context
    }
    throw $e;
}

Prevention

When it happens

Trigger: Rendering {{ foo }} or {% if foo %} where 'foo' was never passed to $twig->render($template, $context) or set by for/set/import.

Common situations: Typos in variable names; forgetting a key in the render context array; relying on PHP notice-suppression semantics that Twig does not replicate; renaming variables after refactoring.

Related errors


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

Appendix: source

Thrown at src/Node/Expression/NameExpression.php:85

                ->string($name)
                ->raw(']')
            ;
        } else {
            if ($this->getAttribute('ignore_strict_check') || !$compiler->getEnvironment()->isStrictVariables()) {
                $compiler
                    ->raw('($context[')
                    ->string($name)
                    ->raw('] ?? null)')
                ;
            } else {
                $compiler
                    ->raw('(isset($context[')
                    ->string($name)
                    ->raw(']) || array_key_exists(')
                    ->string($name)
                    ->raw(', $context) ? $context[')
                    ->string($name)
                    ->raw('] : (function () { throw new RuntimeError(\'Variable ')
                    ->string($name)
                    ->raw(' does not exist.\', ')
                    ->repr($this->lineno)
                    ->raw(', $this->source); })()')
                    ->raw(')')
                ;
            }
        }
    }

    /**
     * @deprecated since Twig 3.11 (to be removed in 4.0)
     */
    public function isSpecial()
    {
        trigger_deprecation('twig/twig', '3.11', 'The "%s()" method is deprecated and will be removed in Twig 4.0.', __METHOD__);

        return isset($this->specialVars[$this->getAttribute('name')]);

View on GitHub (pinned to a414c3a491)