twigphp/Twig · error · SyntaxError

An escaping strategy must be a string or false.

Error message

An escaping strategy must be a string or false.

What it means

Thrown by AutoEscapeTokenParser::parse when the {% autoescape %} tag is given an expression that is not a constant string (or false). Twig requires the escaping strategy to be statically known at compile time so it can bake it into the compiled template. Non-constant expressions (variables, function calls) are rejected with a SyntaxError at parse time.

Solutions

  1. Use a literal string: {% autoescape 'html' %}, 'js', 'css', 'url', or false.
  2. Move dynamic strategy selection to PHP by pushing a custom Escaper/Guard escaper or setting autoescape as a closure in the Environment options.
  3. If you only need conditional output handling, render with separate includes per strategy instead of a variable strategy.
  4. Bare {% autoescape %} defaults to 'html' — omit the argument if html is wanted.

Example fix

{% autoescape strategyName %}...{% endautoescape %}

{# after #}
{% autoescape 'html' %}...{% endautoescape %}
Defensive patterns

Strategy: validation

Validate before calling

$allowed = ['html', 'js', 'css', 'url', false];
if (!in_array($strategy, $allowed, true)) {
    throw new \InvalidArgumentException('autoescape strategy must be a literal html|js|css|url|false');
}

Try / catch

try {
    $twig->parse($twig->tokenize(new \Twig\Source($code, $name)));
} catch (\Twig\Error\SyntaxError $e) {
    if (str_contains($e->getMessage(), 'escaping strategy must be a string')) {
        // report template line and fix the autoescape argument
    }
    throw $e;
}

Prevention

When it happens

Trigger: Writing {% autoescape someVar %} ... {% endautoescape %} or {% autoescape escape_strategy_from_config %} where the argument parses as any expression other than a ConstantExpression (e.g. a name, array, or function call).

Common situations: Trying to make the escaping strategy dynamic based on request/config data; assuming {% autoescape %} accepts a runtime variable; migrating code that computed the strategy in a template instead of at environment setup.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/TokenParser/AutoEscapeTokenParser.php:37

/**
 * Marks a section of a template to be escaped or not.
 *
 * @internal
 */
final class AutoEscapeTokenParser extends AbstractTokenParser
{
    public function parse(Token $token): Node
    {
        $lineno = $token->getLine();
        $stream = $this->parser->getStream();

        if ($stream->test(Token::BLOCK_END_TYPE)) {
            $value = 'html';
        } else {
            $expr = $this->parser->parseExpression();
            if (!$expr instanceof ConstantExpression) {
                throw new SyntaxError('An escaping strategy must be a string or false.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
            }
            $value = $expr->getAttribute('value');
        }

        $stream->expect(Token::BLOCK_END_TYPE);
        $body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
        $stream->expect(Token::BLOCK_END_TYPE);

        return new AutoEscapeNode($value, $body, $lineno);
    }

    public function decideBlockEnd(Token $token): bool
    {
        return $token->test('endautoescape');
    }

    public function getTag(): string
    {

View on GitHub (pinned to a414c3a491)