twigphp/Twig · error · SyntaxError
You cannot assign a value to
Error message
You cannot assign a value to "%s".
What it means
TempNameExpression reserves identifiers for Twig's internal temporary variables and rejects using the reserved boolean/null literals (true, false, none, null) as assignment targets. This compile-time check prevents users from shadowing values Twig's expression parser treats specially.
Solutions
- Rename the variable to something other than true/false/none/null
- If generating templates, sanitize variable names against the reserved list ['true','false','none','null']
Example fix
// before
{% set none = value %}
// after
{% set noValue = value %} Defensive patterns
Strategy: validation
Validate before calling
$reserved = ['true','false','none','null'];
if (in_array(strtolower($name), $reserved, true)) {
throw new InvalidArgumentException("Cannot use reserved name '$name' as variable");
} Type guard
function isReservedTwigName(string $name): bool {
return in_array(strtolower($name), ['true','false','none','null'], true);
} Try / catch
try {
$twig->parse($twig->tokenize(new \Twig\Source($code, $name)));
} catch (\Twig\Error\SyntaxError $e) {
// handle reserved-name assignment
} Prevention
- Never name template variables after literals
- Sanitize identifiers in template-generation code
- Lint generated templates before writing them
When it happens
Trigger: Writing {% set true = x %}, {% set null = 1 %} or capturing a for-loop target named 'none' — any assignment whose name lowercases to true/false/none/null.
Common situations: Mistakenly setting a variable named after a literal; template translation or code-generation output that emits reserved words as variable names.
Related errors
- Calling the "parent" function outside of a block is…
- Calling the "parent" function on a template that does not…
- The argument " " in macro " " cannot be defined because the…
- A template that extends another one cannot include content…
- Positional arguments cannot be used after named arguments…
AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13).
Data as JSON: /api/errors/3dcf5ddb0bdf8689.
Report an issue: GitHub.
Appendix: source
Thrown at src/Node/Expression/TempNameExpression.php:32
use Twig\Compiler;
use Twig\Error\SyntaxError;
class TempNameExpression extends AbstractExpression
{
// 4.0: re-evaluate "varargs" here once the implicit macro varargs bucket is removed
// (see MacroNode::VARARGS_NAME); the other names map to compiled variables ($context,
// $macros, $blocks, $this) and must stay.
public const RESERVED_NAMES = ['varargs', 'context', 'macros', 'blocks', 'this'];
// Prefix applied to reserved names so their compiled PHP variables cannot clash
// with the internal ones ($varargs, $context, $macros, $blocks, $this)
public const RESERVED_NAME_PREFIX = "\u{035C}";
public function __construct(string|int|null $name, int $lineno)
{
// All names supported by ExpressionParser::parsePrimaryExpression() should be excluded
if ($name && \in_array(strtolower($name), ['true', 'false', 'none', 'null'], true)) {
throw new SyntaxError(\sprintf('You cannot assign a value to "%s".', $name), $lineno);
}
if (self::class === static::class) {
trigger_deprecation('twig/twig', '3.15', 'The "%s" class is deprecated.', self::class);
}
if (null !== $name && (\is_int($name) || ctype_digit($name))) {
$name = (int) $name;
} elseif (\in_array($name, self::RESERVED_NAMES, true)) {
$name = self::RESERVED_NAME_PREFIX.$name;
}
parent::__construct([], ['name' => $name], $lineno);
}
public function compile(Compiler $compiler): void
{
if (null === $this->getAttribute('name')) {View on GitHub (pinned to a414c3a491)