{"record":{"id":"4fde1f4033d41f6d","repo":"symfony/symfony","slug":"a-message-inside-a-trans-tag-must-be-a-simple-text","errorCode":null,"errorMessage":"A message inside a trans tag must be a simple text.","messagePattern":"A message inside a trans tag must be a simple text\\.","errorType":"exception","errorClass":"Twig\\Error\\SyntaxError","httpStatus":null,"severity":"error","filePath":"src/Symfony/Bridge/Twig/TokenParser/TransTokenParser.php","lineNumber":73,"sourceCode":"                $stream->next();\n                $domain = $this->parser->parseExpression();\n            }\n\n            if ($stream->test('into')) {\n                // {% trans into \"fr\" %}\n                $stream->next();\n                $locale = $this->parser->parseExpression();\n            } elseif (!$stream->test(Token::BLOCK_END_TYPE)) {\n                throw new SyntaxError('Unexpected token. Twig was looking for the \"with\", \"from\", or \"into\" keyword.', $stream->getCurrent()->getLine(), $stream->getSourceContext());\n            }\n        }\n\n        // {% trans %}message{% endtrans %}\n        $stream->expect(Token::BLOCK_END_TYPE);\n        $body = $this->parser->subparse($this->decideTransFork(...), true);\n\n        if (!$body instanceof TextNode && !$body instanceof AbstractExpression) {\n            throw new SyntaxError('A message inside a trans tag must be a simple text.', $body->getTemplateLine(), $stream->getSourceContext());\n        }\n\n        $stream->expect(Token::BLOCK_END_TYPE);\n\n        return new TransNode($body, $domain, $count, $vars, $locale, $lineno);\n    }\n\n    public function decideTransFork(Token $token): bool\n    {\n        return $token->test(['endtrans']);\n    }\n\n    public function getTag(): string\n    {\n        return 'trans';\n    }\n}\n","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/symfony/symfony/blob/698e28026c22cf35d032cdb6e800db48b1535790/src/Symfony/Bridge/Twig/TokenParser/TransTokenParser.php#L55-L91","documentation":"Thrown by the {% trans %} token parser when the body between {% trans %} and {% endtrans %} is not a single TextNode or an AbstractExpression. The trans tag requires its message to be a translatable unit (pure static text, optionally with placeholder expressions), so compound nodes like nested blocks, HTML elements, or multiple concatenated pieces are rejected.","triggerScenarios":"Placing non-text content inside the trans tag such as nested {% %} blocks, raw HTML tags that produce non-TextNode AST, or multi-node bodies that subparse into something other than TextNode/AbstractExpression.","commonSituations":"Wrapping a complex template fragment in {% trans %}...{% endtrans %} that includes conditionals, loops, or HTML. Attempting to translate a block that contains variable interpolations beyond simple %placeholder% expressions. Mixing trans with trans_default_domain incorrectly.","solutions":["Keep the trans body to plain static text only, e.g. {% trans %}Hello{% endtrans %}.","For dynamic content, use placeholders: {% trans %}Hello %name%{% endtrans %} with {% trans with {'%name%': user.name} %}.","Move complex/nested markup outside the trans tag and translate only the static sentence."],"exampleFix":"// before\n{% trans %}\n  <p>Hello {{ user.name }}</p>\n{% endtrans %}\n\n// after\n<p>{% trans with {'%name%': user.name} %}Hello %name%{% endtrans %}</p>","handlingStrategy":"validation","validationCode":"// Validate trans bodies with the linter before deploying\n// php bin/console lint:twig templates/\n// Keep trans bodies to plain text + %placeholder% expressions only.","typeGuard":null,"tryCatchPattern":"try {\n    $twig->render($template, $vars);\n} catch (\\Twig\\Error\\SyntaxError $e) {\n    if (str_contains($e->getMessage(), 'must be a simple text')) {\n        // simplify the trans body to plain text\n    }\n    throw $e;\n}","preventionTips":["Keep {% trans %} bodies to static text and %placeholders% only; move markup/conditionals outside.","Lint templates in CI."],"tags":["twig","translation","syntax-error","trans-tag","ast"],"analyzedSha":"698e28026c22cf35d032cdb6e800db48b1535790","analyzedAt":"2026-08-06T23:40:49.025Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}