twigphp/Twig · error · SyntaxError

Unexpected end of template. Twig was looking for the…

Error message

Unexpected end of template. Twig was looking for the following tags "else", "elseif", or "endif" to close the "if" block started at line %d).

What it means

Thrown by IfTokenParser::parse when template parsing reaches the end of the template (or an unexpected closing tag) without finding {% else %}, {% elseif %}, or {% endif %} to close an {% if %} opened at the given line. The default case of the subparse loop converts the token into this SyntaxError so the developer knows exactly where the unclosed if started.

Solutions

  1. Add the missing {% endif %} for the if started at the reported line.
  2. Check that elseif/else branches are all properly closed before the enclosing endblock/endmacro.
  3. Recount nesting after a refactor — an extra {% endif %} elsewhere may have consumed this one.
  4. Use an editor with Twig syntax highlighting / lint to spot unbalanced tags.

Example fix

{% if cond %}
  <p>hi</p>

{# after #}
{% if cond %}
  <p>hi</p>
{% endif %}
Defensive patterns

Strategy: validation

Try / catch

try {
    $twig->parse($twig->tokenize(new \Twig\Source($code, $name)));
} catch (\Twig\Error\SyntaxError $e) {
    if (str_contains($e->getMessage(), 'looking for the following tags')) {
        // use the reported start line to locate the unclosed {% if %}
    }
    throw $e;
}

Prevention

When it happens

Trigger: An {% if %} block whose {% endif %} is missing, deleted, or placed after an {% endblock %}/{% endmacro %} that ends the parse region; EOF hit while subparsing the if body.

Common situations: Large template edits that accidentally remove an endif; nesting ifs inside blocks/macros and closing the outer construct first; conditional blocks generated by partials where endif was expected in another fragment.

Related errors


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

Appendix: source

Thrown at src/TokenParser/IfTokenParser.php:67

                case 'else':
                    $stream->expect(Token::BLOCK_END_TYPE);
                    $else = $this->parser->subparse([$this, 'decideIfEnd']);
                    break;

                case 'elseif':
                    $expr = $this->parser->parseExpression();
                    $stream->expect(Token::BLOCK_END_TYPE);
                    $body = $this->parser->subparse([$this, 'decideIfFork']);
                    $tests[] = $expr;
                    $tests[] = $body;
                    break;

                case 'endif':
                    $end = true;
                    break;

                default:
                    throw new SyntaxError(\sprintf('Unexpected end of template. Twig was looking for the following tags "else", "elseif", or "endif" to close the "if" block started at line %d).', $lineno), $stream->getCurrent()->getLine(), $stream->getSourceContext());
            }
        }

        $stream->expect(Token::BLOCK_END_TYPE);

        return new IfNode(new Nodes($tests), $else, $lineno);
    }

    public function decideIfFork(Token $token): bool
    {
        return $token->test(['elseif', 'else', 'endif']);
    }

    public function decideIfEnd(Token $token): bool
    {
        return $token->test(['endif']);
    }

View on GitHub (pinned to a414c3a491)