{"record":{"id":"a2d064ddb9873806","repo":"symfony/routing","slug":"variable-name-s-cannot-be-longer-than-d-characters-in-route","errorCode":null,"errorMessage":"Variable name \"%s\" cannot be longer than %d characters in route pattern \"%s\". Please use a shorter name.","messagePattern":"Variable name \"(.+?)\" cannot be longer than (.+?) characters in route pattern \"(.+?)\"\\. Please use a shorter name\\.","errorType":"exception","errorClass":"DomainException","httpStatus":null,"severity":"error","filePath":"RouteCompiler.php","lineNumber":154,"sourceCode":"            } elseif ($useUtf8) {\n                preg_match('/.$/u', $precedingText, $precedingChar);\n                $precedingChar = $precedingChar[0];\n            } else {\n                $precedingChar = substr($precedingText, -1);\n            }\n            $isSeparator = '' !== $precedingChar && str_contains(static::SEPARATORS, $precedingChar);\n\n            // A PCRE subpattern name must start with a non-digit. Also a PHP variable cannot start with a digit so the\n            // variable would not be usable as a Controller action argument.\n            if (preg_match('/^\\d/', $varName)) {\n                throw new \\DomainException(\\sprintf('Variable name \"%s\" cannot start with a digit in route pattern \"%s\". Please use a different name.', $varName, $pattern));\n            }\n            if (\\in_array($varName, $variables)) {\n                throw new \\LogicException(\\sprintf('Route pattern \"%s\" cannot reference variable name \"%s\" more than once.', $pattern, $varName));\n            }\n\n            if (\\strlen($varName) > self::VARIABLE_MAXIMUM_LENGTH) {\n                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));\n            }\n\n            if ($isSeparator && $precedingText !== $precedingChar) {\n                $tokens[] = ['text', substr($precedingText, 0, -\\strlen($precedingChar))];\n            } elseif (!$isSeparator && '' !== $precedingText) {\n                $tokens[] = ['text', $precedingText];\n            }\n\n            $regexp = $route->getRequirement($varName);\n            if (null === $regexp) {\n                $followingPattern = substr($pattern, $pos);\n                // Find the next static character after the variable that functions as a separator. By default, this separator and '/'\n                // are disallowed for the variable. This default requirement makes sure that optional variables can be matched at all\n                // and that the generating-matching-combination of URLs unambiguous, i.e. the params used for generating the URL are\n                // the same that will be matched. Example: new Route('/{page}.{_format}', ['_format' => 'html'])\n                // If {page} would also match the separating dot, {_format} would never match as {page} will eagerly consume everything.\n                // Also even if {_format} was not optional the requirement prevents that {page} matches something that was originally\n                // part of {_format} when generating the URL, e.g. _format = 'mobile.html'.","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/symfony/routing/blob/83fa223250b50f4f018c011e101c330e65ac63cc/RouteCompiler.php#L136-L172","documentation":"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.","triggerScenarios":"Compiling a route with an overly long placeholder, e.g. /search/{thisIsAVeryLongDescriptiveVariableNameExceedingLimit}.","commonSituations":"Auto-generated parameters from long field/column names; developers using verbose descriptive placeholder names; code generators embedding fully qualified names as placeholders.","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."],"exampleFix":"// before\n$route = new Route('/users/{userAccountPrimaryEmailAddressForLookup}');\n\n// after\n$route = new Route('/users/{userEmail}');","handlingStrategy":"validation","validationCode":"const MAX = 32; // RouteCompiler::VARIABLE_MAXIMUM_LENGTH\npreg_match_all('/\\{(!)?([^}]+)\\}/', $route->getPath(), $m);\nforeach ($m[2] as $var) {\n    if (mb_strlen($var) > MAX) {\n        throw new \\InvalidArgumentException(\"Variable '$var' exceeds $MAX characters.\");\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    (new RouteCompiler())->compile($route);\n} catch (\\DomainException $e) {\n    // shorten the variable name and recompile\n}","preventionTips":["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."],"tags":["routing","symfony","variable-naming","length-limit"],"backgroundTag":"value-out-of-range","analyzedSha":"83fa223250b50f4f018c011e101c330e65ac63cc","analyzedAt":"2026-09-14T03:19:46.280Z","contentChangedAt":"2026-09-14T03:19:46.280Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}