symfony/routing · error · DomainException
Variable name " " cannot start with a digit in route…
Error message
Variable name "%s" cannot start with a digit in route pattern "%s". Please use a different name.
What it means
Route variable names extracted from {placeholders} must start with a non-digit: PCRE subpattern names and PHP variables cannot begin with a digit, so the value could never be used as a controller action argument. compilePattern throws a DomainException when the variable name matches /^\d/.
Solutions
- Rename the variable to start with a letter or underscore, e.g. {2fa_code} → {twoFactorCode} or {_2fa_code}.
- Pass the numeric part as a fixed prefix or default instead of a variable, e.g. /blog/2fa/{code}.
- Search route definitions with a regex like \{\d for offending placeholders.
Example fix
// before
$route = new Route('/login/{2fa_code}');
// after
$route = new Route('/login/{twoFactorCode}'); Defensive patterns
Strategy: validation
Validate before calling
preg_match_all('/\{(!)?([^}]+)\}/', $route->getPath(), $m);
foreach ($m[2] as $var) {
if (preg_match('/^\d/', $var)) {
throw new \InvalidArgumentException("Variable '$var' must not start with a digit.");
}
} Try / catch
try {
(new RouteCompiler())->compile($route);
} catch (\DomainException $e) {
// rename the offending variable and recompile
} Prevention
- Adopt a naming convention for placeholders (camelCase starting with a letter).
- When generating routes from data, sanitize keys: preg_replace('/^\d+/', '_', $key).
- Spell out numbers in parameter names ({twoFactorCode}, not {2fa}).
When it happens
Trigger: Compiling a route with a placeholder like /blog/{2fa_code}, /items/{0id}, or any {<digit>...} variable name.
Common situations: Placeholders meant to denote numbered items ({1st}, {2fa}); generated route names from data with numeric keys; typos where a digit replaced a letter.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- Variable name " " cannot be longer than characters 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/56638764df803d66.
Report an issue: GitHub.
Appendix: source
Thrown at RouteCompiler.php:147
$varName = $match[2][0];
// get all static text preceding the current variable
$precedingText = substr($pattern, $pos, $match[0][1] - $pos);
$pos = $match[0][1] + \strlen($match[0][0]);
if (!\strlen($precedingText)) {
$precedingChar = '';
} 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);View on GitHub (pinned to 83fa223250)