twigphp/Twig · error · SyntaxError

Unknown " " option.

Error message

Unknown "%s" option.

What it means

Thrown by DeprecatedTokenParser::parse when the {% deprecated %} tag receives an option key other than 'package' or 'version'. The parser switches over known option names and any other key (the loop iterates string arguments) hits the default case, raising a SyntaxError. Only package and version metadata are supported for deprecation notices.

Solutions

  1. Use only supported options: {% deprecated 'message' package='vendor/pkg' version='1.2' %}.
  2. Remove the unknown option key.
  3. Move extra rationale into the free-text message part of the tag.

Example fix

{% deprecated since="2.0" %}

{# after #}
{% deprecated 'The "foo" filter is deprecated.' package='vendor/pkg' version='2.0' %}
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(), 'Unknown') && str_contains($e->getMessage(), 'option')) {
        // point developer to supported keys: package, version
    }
    throw $e;
}

Prevention

When it happens

Trigger: Writing {% deprecated since="1.2" %} or {% deprecated reason="old" %} — any option key besides package/version triggers the error at the option's line.

Common situations: Confusing {% deprecated %} with PHP docblock-style @deprecated annotations and writing since/reason keys; copying syntax from other template engines or from trigger_deprecation() helper calls.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at src/TokenParser/DeprecatedTokenParser.php:52

    {
        $stream = $this->parser->getStream();
        $expr = $this->parser->parseExpression();
        $node = new DeprecatedNode($expr, $token->getLine());

        while ($stream->test(Token::NAME_TYPE)) {
            $k = $stream->getCurrent()->getValue();
            $stream->next();
            $stream->expect(Token::OPERATOR_TYPE, '=');

            switch ($k) {
                case 'package':
                    $node->setNode('package', $this->parser->parseExpression());
                    break;
                case 'version':
                    $node->setNode('version', $this->parser->parseExpression());
                    break;
                default:
                    throw new SyntaxError(\sprintf('Unknown "%s" option.', $k), $stream->getCurrent()->getLine(), $stream->getSourceContext());
            }
        }

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

        return $node;
    }

    public function getTag(): string
    {
        return 'deprecated';
    }
}

View on GitHub (pinned to a414c3a491)