symfony/symfony · error · RuntimeException
Unable to use expressions as the Symfony ExpressionLanguage
Error message
Unable to use expressions as the Symfony ExpressionLanguage component is not installed. Try running "composer require symfony/expression-language".
What it means
Thrown by SecurityExtension::createExpression() when the container reports that symfony/expression-language will NOT be available at runtime (ContainerBuilder::willBeAvailable returns false) while compiling an expression-based access rule or voter. Expressions in security require the ExpressionLanguage component; its absence makes expression config unusable, so compilation aborts.
Source
Thrown at src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php:957
$listener->replaceArgument(1, new Reference($userProvider));
$listener->replaceArgument(2, new Reference('security.user_checker.'.$id));
$listener->replaceArgument(3, $id);
$listener->replaceArgument(6, $config['parameter']);
$listener->replaceArgument(7, $config['role']);
$listener->replaceArgument(9, $stateless);
$listener->replaceArgument(11, $config['target_route']);
return $switchUserListenerId;
}
private function createExpression(ContainerBuilder $container, string $expression): Reference
{
if (isset($this->expressions[$id = '.security.expression.'.ContainerBuilder::hash($expression)])) {
return $this->expressions[$id];
}
if (!$container::willBeAvailable('symfony/expression-language', ExpressionLanguage::class, ['symfony/security-bundle'])) {
throw new \RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed. Try running "composer require symfony/expression-language".');
}
$container
->register($id, Expression::class)
->addArgument($expression)
;
return $this->expressions[$id] = new Reference($id);
}
private function createRequestMatcher(ContainerBuilder $container, ?string $path = null, ?string $host = null, ?int $port = null, array $methods = [], ?array $ips = null, array $attributes = []): Reference
{
if ($methods) {
$methods = array_map('strtoupper', $methods);
}
if ($ips) {
foreach ($ips as $ip) {View on GitHub (pinned to 698e28026c)
Solutions
- Install the component: composer require symfony/expression-language.
- Ensure it is installed in the environment that compiles the container (avoid --no-dev if it is a dev requirement; better: make it a prod dependency).
- Verify availability: composer show symfony/expression-language.
- If you do not want the dependency, remove all allow_if / expression-based security config.
Example fix
# before: security.yaml uses allow_if without the component
security:
access_control:
- { path: ^/admin, allow_if: "'ROLE_ADMIN' in roles" }
# RuntimeException: Unable to use expressions as the Symfony ExpressionLanguage component is not installed...
# after
$ composer require symfony/expression-language Defensive patterns
Strategy: validation
Validate before calling
// Guard expression config on component presence before compiling
if (!class_exists(\Symfony\Component\ExpressionLanguage\ExpressionLanguage::class)) {
foreach ($accessControl as $rule) {
if (!empty($rule['allow_if'])) {
throw new \LogicException('allow_if requires symfony/expression-language; run composer require symfony/expression-language');
}
}
} Type guard
function expressionLanguageAvailable(): bool
{
return class_exists(\Symfony\Component\ExpressionLanguage\ExpressionLanguage::class);
} Prevention
- Require symfony/expression-language whenever allow_if or expression voters are used.
- Keep it as a prod dependency so prod container compiles succeed.
- Audit security config for allow_if before removing the component.
- Validate config in CI with cache:clear --env=prod.
When it happens
Trigger: Using `allow_if` expressions in access_control, expression voters, or deny/allow expression config while symfony/expression-language is not installed or is registered as a dev-only package excluded from the compiled container's available packages.
Common situations: Adding an `allow_if` to access_control in a project without expression-language; expression-language required only in dev (so prod container compile fails); removing the component while leaving allow_if rules; willBeAvailable excluding it due to a version conflict.
Related errors
- The "request_matcher" option should not be specified alongsi
- The "route" option should not be specified alongside "attrib
- One or more access control items are empty. Did you accident
- Passing a $field to the "is_granted_for_user()" function req
- Using the "access_decision_for_user()" function requires sym
AI-assisted analysis of symfony/symfony@698e28026c (2026-08-06).
Data as JSON: /api/errors/67447052bbf5f86b.
Report an issue: GitHub.