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
- Pass the missing variable in the template context from the controller/action
- Guard with the `default` filter or defined test: `{{ user.profile.name|default('') }}` or `{% if user.profile is defined and user.profile is not null %}`
- Disable strict_variables if the null-access is intentional (not recommended; hides bugs)
- 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
- Always provide default context values for optional template variables
- Use |default() or `is defined` guards on chained attribute access
- Keep strict_variables=true in dev/CI to catch these before production
- Initialize nullable Doctrine relations or check them before rendering
- Validate that controller-rendered context matches the template's expected variables
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
- Neither the property "%1$s" nor one of the methods…
- Attribute " " does not exist for Node " ".
- Unknown " " configuration.
- The " " modifier takes exactly one argument (0 given).
- The " " modifier takes exactly one argument (2 given).
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)