twigphp/Twig · error · SyntaxError
Unexpected end of template.
Error message
Unexpected end of template.
What it means
TokenStream::next() advances past the last token; when there is no next token, Twig throws 'Unexpected end of template.' This means the template's syntax required more tokens than exist — typically an unclosed construct.
Solutions
- Check the reported line (the last parsed line) for an unclosed tag or expression and add the matching end tag
- Verify the template file was fully deployed/saved and is not truncated
- Run twig-lint (bin/console lint:twig in Symfony) to catch the unclosed construct before deployment
Example fix
// before
{% if user %}
{{ user.name }}
// after
{% if user %}
{{ user.name }}
{% endif %} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-compile templates to catch EOF/unclosed constructs before render $env->parse($env->tokenize(new Source($template, $name)));
Try / catch
try {
$html = $twig->render($name, $context);
} catch (SyntaxError $e) {
if (str_contains($e->getMessage(), 'Unexpected end of template')) {
// log template name + line; alert that a tag is unclosed or file truncated
}
throw $e;
} Prevention
- Always close {% if %}/{% for %}/{% block %}/{% macro %} with their end tags
- Verify deployed template files match the repository (checksums/CI artifact)
- Add twig linting (lint:twig) to CI so truncation and unclosed tags fail the build
When it happens
Trigger: A template ending while the parser still expects tokens: unclosed {% if %}/{% for %}/{% block %}, an unfinished expression like '{{ foo', or a missing {% endtag %}; any parser call to next()/expect() at EOF triggers it.
Common situations: Truncated template files from failed deploys/partial saves; copy-pasting template fragments without their closing tags; forgetting {% endif %}, {% endfor %}, or {% endblock %}.
Related errors
- Unexpected character
- Unexpected end of template. Twig was looking for the…
- The variadic argument
- The variadic argument
- When using set, you must have the same number of variables…
AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13).
Data as JSON: /api/errors/deb2be73808002ba.
Report an issue: GitHub.
Appendix: source
Thrown at src/TokenStream.php:53
}
public function __toString(): string
{
return implode("\n", $this->tokens);
}
public function injectTokens(array $tokens): void
{
$this->tokens = array_merge(\array_slice($this->tokens, 0, $this->current), $tokens, \array_slice($this->tokens, $this->current));
}
/**
* Sets the pointer to the next token and returns the old one.
*/
public function next(): Token
{
if (!isset($this->tokens[++$this->current])) {
throw new SyntaxError('Unexpected end of template.', $this->tokens[$this->current - 1]->getLine(), $this->source);
}
return $this->tokens[$this->current - 1];
}
/**
* Tests a token, sets the pointer to the next one and returns it or throws a syntax error.
*
* @return Token|null The next token if the condition is true, null otherwise
*/
public function nextIf($primary, $secondary = null)
{
return $this->tokens[$this->current]->test($primary, $secondary) ? $this->next() : null;
}
/**
* Tests a token and returns it or throws a syntax error.
*/View on GitHub (pinned to a414c3a491)