{"record":{"id":"96c2402b3f0a3b05","repo":"twigphp/Twig","slug":"a-block-must-start-with-a-tag-name","errorCode":null,"errorMessage":"A block must start with a tag name.","messagePattern":"A block must start with a tag name\\.","errorType":"exception","errorClass":"SyntaxError","httpStatus":null,"severity":"error","filePath":"src/Parser.php","lineNumber":201,"sourceCode":"                    $token = $this->stream->next();\n                    $rv[] = new TextNode($token->getValue(), $token->getLine());\n                    break;\n\n                case $this->stream->getCurrent()->test(Token::VAR_START_TYPE):\n                    $token = $this->stream->next();\n                    $expr = $this->parseExpression();\n                    $this->stream->expect(Token::VAR_END_TYPE);\n                    $node = new PrintNode($expr, $token->getLine());\n                    NodeDocumentation::add($node, $token);\n                    $rv[] = $node;\n                    break;\n\n                case $this->stream->getCurrent()->test(Token::BLOCK_START_TYPE):\n                    $startToken = $this->stream->next();\n                    $token = $this->getCurrentToken();\n\n                    if (!$token->test(Token::NAME_TYPE)) {\n                        throw new SyntaxError('A block must start with a tag name.', $token->getLine(), $this->stream->getSourceContext());\n                    }\n\n                    if (null !== $test && $test($token)) {\n                        if ($dropNeedle) {\n                            $this->stream->next();\n                        }\n\n                        if (1 === \\count($rv)) {\n                            return $rv[0];\n                        }\n\n                        return new Nodes($rv, $lineno);\n                    }\n\n                    if (!$subparser = $this->env->getTokenParser($token->getValue())) {\n                        if (null !== $test) {\n                            $e = new SyntaxError(\\sprintf('Unexpected \"%s\" tag', $token->getValue()), $token->getLine(), $this->stream->getSourceContext());\n","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/twigphp/Twig/blob/a414c3a491defb5a60f2fc88ef79ff37c90010cd/src/Parser.php#L183-L219","documentation":"After a {% token start, the parser expects an identifier (the tag name such as if, block, extends). If the next token is not a NAME_TYPE token, Parser::subparse throws this SyntaxError because there is no valid Twig tag to dispatch to.","triggerScenarios":"Typing an invalid tag start like {% 123 %}, {% \"foo\" %}, {% %}, or {% $var %}; unescaped stray braces that begin a block; broken operators such as {% == x %}.","commonSituations":"Typos in templates; JavaScript or CSS containing {{/{% sequences not wrapped in {% raw %} or {% verbatim %}; templating a language whose syntax collides with Twig delimiters; generation bugs producing empty tag bodies.","solutions":["Fix the tag so it starts with a valid tag name after {%","Wrap literal {{ or {% sequences in {% raw %} ... {% endraw %} (or {% verbatim %})","Check for stray/mismatched {% delimiters from string interpolation or JS templating","If generating templates, validate that every {% is followed by an identifier"],"exampleFix":"// before\n{% 123 %}\n// after\n{% if page == 123 %}...{% endif %}","handlingStrategy":"validation","validationCode":"if (preg_match('/{%(?!\\\\s*[a-zA-Z_][a-zA-Z0-9_]*)[^%]*%}/', $tpl)) { /* tag does not start with a name */ }","typeGuard":null,"tryCatchPattern":"try { $env->render($name); } catch (\\Twig\\Error\\SyntaxError $e) { if (str_contains($e->getMessage(), 'block must start with')) { /* malformed tag */ } }","preventionTips":["Always put a tag name right after {%","Wrap literal {{/{% content in {% raw %} blocks","Lint templates in CI before deployment"],"tags":["twig","parser","syntax-error","template-syntax"],"backgroundTag":"invalid-template-structure","analyzedSha":"a414c3a491defb5a60f2fc88ef79ff37c90010cd","analyzedAt":"2026-09-13T15:10:46.849Z","contentChangedAt":"2026-09-13T15:10:46.849Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}