symfony/routing · error · DomainException
Variable name " " cannot be longer than characters in route…
Error message
Variable name "%s" cannot be longer than %d characters in route pattern "%s". Please use a shorter name.
What it means
Variable names are capped at RouteCompiler::VARIABLE_MAXIMUM_LENGTH (32 characters) because the name becomes a PCRE named subpattern and PHP variable, which should stay usable as a controller argument. compilePattern throws a DomainException when strlen($varName) exceeds that limit.
Solutions
- Shorten the placeholder to 32 characters or fewer, e.g. {userAccountEmailAddress} instead of the long name.
- Generate concise parameter names programmatically (abbreviate, hash, or index) when routes are built from schema metadata.
- Check VARIABLE_MAXIMUM_LENGTH (32) and add a pre-validation on generated names.
Example fix
// before
$route = new Route('/users/{userAccountPrimaryEmailAddressForLookup}');
// after
$route = new Route('/users/{userEmail}'); Defensive patterns
Strategy: validation
Validate before calling
const MAX = 32; // RouteCompiler::VARIABLE_MAXIMUM_LENGTH
preg_match_all('/\{(!)?([^}]+)\}/', $route->getPath(), $m);
foreach ($m[2] as $var) {
if (mb_strlen($var) > MAX) {
throw new \InvalidArgumentException("Variable '$var' exceeds $MAX characters.");
}
} Try / catch
try {
(new RouteCompiler())->compile($route);
} catch (\DomainException $e) {
// shorten the variable name and recompile
} Prevention
- Keep placeholder names short; put descriptive data in controller defaults instead.
- When auto-generating names from schema fields, abbreviate or hash long identifiers.
- Assert name length in route factory helpers.
When it happens
Trigger: Compiling a route with an overly long placeholder, e.g. /search/{thisIsAVeryLongDescriptiveVariableNameExceedingLimit}.
Common situations: Auto-generated parameters from long field/column names; developers using verbose descriptive placeholder names; code generators embedding fully qualified names as placeholders.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Variable name " " cannot start with a digit in route…
- Parameter " " for route " " must match " " (" " given) to…
- Parameters for route
- Route aliases cannot be used on non-invokable class
- The " ()" method must not be called.
AI-assisted analysis of symfony/routing@83fa223250 (2026-09-14).
Data as JSON: /api/errors/a2d064ddb9873806.
Report an issue: GitHub.
Appendix: source
Thrown at RouteCompiler.php:154
} elseif ($useUtf8) {
preg_match('/.$/u', $precedingText, $precedingChar);
$precedingChar = $precedingChar[0];
} else {
$precedingChar = substr($precedingText, -1);
}
$isSeparator = '' !== $precedingChar && str_contains(static::SEPARATORS, $precedingChar);
// A PCRE subpattern name must start with a non-digit. Also a PHP variable cannot start with a digit so the
// variable would not be usable as a Controller action argument.
if (preg_match('/^\d/', $varName)) {
throw new \DomainException(\sprintf('Variable name "%s" cannot start with a digit in route pattern "%s". Please use a different name.', $varName, $pattern));
}
if (\in_array($varName, $variables)) {
throw new \LogicException(\sprintf('Route pattern "%s" cannot reference variable name "%s" more than once.', $pattern, $varName));
}
if (\strlen($varName) > self::VARIABLE_MAXIMUM_LENGTH) {
throw new \DomainException(\sprintf('Variable name "%s" cannot be longer than %d characters in route pattern "%s". Please use a shorter name.', $varName, self::VARIABLE_MAXIMUM_LENGTH, $pattern));
}
if ($isSeparator && $precedingText !== $precedingChar) {
$tokens[] = ['text', substr($precedingText, 0, -\strlen($precedingChar))];
} elseif (!$isSeparator && '' !== $precedingText) {
$tokens[] = ['text', $precedingText];
}
$regexp = $route->getRequirement($varName);
if (null === $regexp) {
$followingPattern = substr($pattern, $pos);
// Find the next static character after the variable that functions as a separator. By default, this separator and '/'
// are disallowed for the variable. This default requirement makes sure that optional variables can be matched at all
// and that the generating-matching-combination of URLs unambiguous, i.e. the params used for generating the URL are
// the same that will be matched. Example: new Route('/{page}.{_format}', ['_format' => 'html'])
// If {page} would also match the separating dot, {_format} would never match as {page} will eagerly consume everything.
// Also even if {_format} was not optional the requirement prevents that {page} matches something that was originally
// part of {_format} when generating the URL, e.g. _format = 'mobile.html'.View on GitHub (pinned to 83fa223250)