{"record":{"id":"b0fda149dd420e66","repo":"symfony/routing","slug":"s-is-not-a-backedenum-class","errorCode":null,"errorMessage":"\"%s\" is not a \"BackedEnum\" class.","messagePattern":"\"(.+?)\" is not a \"BackedEnum\" class\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"Requirement/EnumRequirement.php","lineNumber":29,"sourceCode":"\nnamespace Symfony\\Component\\Routing\\Requirement;\n\nuse Symfony\\Component\\Routing\\Exception\\InvalidArgumentException;\n\nfinal class EnumRequirement implements \\Stringable\n{\n    private string $requirement;\n\n    /**\n     * @template T of \\BackedEnum\n     *\n     * @param class-string<T>|list<T> $cases\n     */\n    public function __construct(string|array $cases = [])\n    {\n        if (\\is_string($cases)) {\n            if (!is_subclass_of($cases, \\BackedEnum::class, true)) {\n                throw new InvalidArgumentException(\\sprintf('\"%s\" is not a \"BackedEnum\" class.', $cases));\n            }\n\n            $cases = $cases::cases();\n        } else {\n            $class = null;\n\n            foreach ($cases as $case) {\n                if (!$case instanceof \\BackedEnum) {\n                    throw new InvalidArgumentException(\\sprintf('Case must be a \"BackedEnum\" instance, \"%s\" given.', get_debug_type($case)));\n                }\n\n                $class ??= $case::class;\n\n                if (!$case instanceof $class) {\n                    throw new InvalidArgumentException(\\sprintf('\"%s::%s\" is not a case of \"%s\".', get_debug_type($case), $case->name, $class));\n                }\n            }\n        }","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/symfony/routing/blob/83fa223250b50f4f018c011e101c330e65ac63cc/Requirement/EnumRequirement.php#L11-L47","documentation":"Requirement/EnumRequirement wraps a BackedEnum (or its cases) into a route requirement that validates path variables. When a string is passed it must be a class-string of a BackedEnum subclass; otherwise InvalidArgumentException is thrown. Plain (non-backed) enums or totally unrelated class names are rejected because their values cannot be turned into string route requirements.","triggerScenarios":"new EnumRequirement(Status::class) where Status is a unit enum (not backed) or a non-enum class; typo in the class name; using an interface or abstract class name.","commonSituations":"Upgrading to Symfony's EnumRequirement and pointing it at a legacy plain enum; copy-pasting a class-string of a DTO; refactoring a backed enum into a plain one and forgetting the requirement.","solutions":["Pass a backed enum class: make the enum 'enum Status: string' or 'enum Status: int'.","Use one of the enum's case values or ::cases() array form instead of an unsupported class.","Fix the class-string typo if it was intended to be a backed enum."],"exampleFix":"// before\nnew EnumRequirement(PlainStatus::class); // plain enum, not backed\n// after\nenum Status: string { case Active = 'active'; }\nnew EnumRequirement(Status::class);","handlingStrategy":"validation","validationCode":"if (!(is_a($enumClass, \\BackedEnum::class, true))) { throw new \\InvalidArgumentException('$enumClass must be a BackedEnum class-string'); }\nnew EnumRequirement($enumClass);","typeGuard":"function isBackedEnumClass(mixed $c): bool { return is_string($c) && is_a($c, \\BackedEnum::class, true); }","tryCatchPattern":"try { $req = new EnumRequirement($cases); } catch (\\InvalidArgumentException $e) { $req = null; // enum is not backed; convert or fix the enum }","preventionTips":["Only reference backed (string/int) enums in route requirements.","Never downgrade a backed enum to a plain enum without updating requirements.","Add a unit test constructing all EnumRequirements from your enum classes."],"tags":["symfony","routing","enum"],"backgroundTag":"invalid-enum-argument","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"}