twigphp/Twig · error · RuntimeError

Impossible to access an attribute/key on a variable…

Error message

Impossible to access an attribute/key on a variable (dynamic message).

What it means

CoreExtension::getAttribute() is the runtime backing for all attribute/key/method access in Twig templates (the `.` and `[]` operators). When the target variable is neither an array, ArrayAccess object, nor object (e.g. null, scalar, string), and Twig is running in strict_variables mode, it throws this RuntimeError with a message describing the variable's actual type. The generic "dynamic message" placeholder in this variant covers the fallthrough branches (null/scalar variables) where the specific message could not be categorized.

Solutions

  1. Pass the missing variable in the template context from the controller/action
  2. Guard with the `default` filter or defined test: `{{ user.profile.name|default('') }}` or `{% if user.profile is defined and user.profile is not null %}`
  3. Disable strict_variables if the null-access is intentional (not recommended; hides bugs)
  4. Fix the data so the intermediate value is never null (initialize relations, provide fallbacks upstream)

Example fix

// before (Twig template)
{{ user.profile.name }}
// after
{{ user.profile.name|default('unknown') }}
Defensive patterns

Strategy: try-catch

Validate before calling

// PHP, before rendering
foreach (['user', 'profile'] as $key) {
    if (!array_key_exists($key, $context)) {
        throw new \LogicException(sprintf('Template context missing "%s".', $key));
    }
}

Type guard

// Twig-side narrowing using built-in tests
{% if user is defined and user is not null and user.profile is defined and user.profile is not null %}
    {{ user.profile.name }}
{% endif %}

Try / catch

try {
    $html = $twig->render('tpl.html.twig', $context);
} catch (\Twig\Error\RuntimeError $e) {
    if (!str_starts_with($e->getMessage(), 'Impossible to access an attribute')) { throw $e; }
    $html = $twig->render('tpl.html.twig', [...$context, 'user' => $fallbackUser]);
}

Prevention

When it happens

Trigger: Accessing `foo.bar` or `foo['bar']` in a template when foo is null, a string, or an int, with strict_variables enabled; rendering a template without passing a variable the template expects (it defaults to null); an optional relation that was not loaded; `{{ user.profile.name }}` when profile is null.

Common situations: Missing template context variables (forgot to pass them from the controller); nullable Doctrine relations accessed in a chain; API responses where an expected key is absent; strict_variables=true in the Twig environment (common in Symfony dev) surfacing bugs that silent null access would hide in prod.

Related errors


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

Appendix: source

Thrown at src/Extension/CoreExtension.php:1823

                } elseif (\is_array($object)) {
                    if (!$object) {
                        $message = \sprintf('Key "%s" does not exist as the sequence/mapping is empty.', $arrayItem);
                    } else {
                        $message = \sprintf('Key "%s" for sequence/mapping with keys "%s" does not exist.', $arrayItem, implode(', ', array_keys($object)));
                    }
                } elseif (Template::ARRAY_CALL === $type) {
                    if (null === $object) {
                        $message = \sprintf('Impossible to access a key ("%s") on a null variable.', $item);
                    } else {
                        $message = \sprintf('Impossible to access a key ("%s") on a %s variable ("%s").', $item, get_debug_type($object), $object);
                    }
                } elseif (null === $object) {
                    $message = \sprintf('Impossible to access an attribute ("%s") on a null variable.', $item);
                } else {
                    $message = \sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s").', $item, get_debug_type($object), $object);
                }

                throw new RuntimeError($message, $lineno, $source);
            }
        }

        $item = (string) $item;

        if (!\is_object($object)) {
            if ($isDefinedTest) {
                return false;
            }

            if ($ignoreStrictCheck || !$env->isStrictVariables()) {
                return;
            }

            if (null === $object) {
                $message = \sprintf('Impossible to invoke a method ("%s") on a null variable.', $item);
            } elseif (\is_array($object)) {
                $message = \sprintf('Impossible to invoke a method ("%s") on a sequence/mapping.', $item);

View on GitHub (pinned to a414c3a491)