symfony/routing · error · InvalidArgumentException

" " is not a "BackedEnum" class.

Error message

"%s" is not a "BackedEnum" class.

What it means

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.

Solutions

  1. Pass a backed enum class: make the enum 'enum Status: string' or 'enum Status: int'.
  2. Use one of the enum's case values or ::cases() array form instead of an unsupported class.
  3. Fix the class-string typo if it was intended to be a backed enum.

Example fix

// before
new EnumRequirement(PlainStatus::class); // plain enum, not backed
// after
enum Status: string { case Active = 'active'; }
new EnumRequirement(Status::class);
Defensive patterns

Strategy: validation

Validate before calling

if (!(is_a($enumClass, \BackedEnum::class, true))) { throw new \InvalidArgumentException('$enumClass must be a BackedEnum class-string'); }
new EnumRequirement($enumClass);

Type guard

function isBackedEnumClass(mixed $c): bool { return is_string($c) && is_a($c, \BackedEnum::class, true); }

Try / catch

try { $req = new EnumRequirement($cases); } catch (\InvalidArgumentException $e) { $req = null; // enum is not backed; convert or fix the enum }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "invalid argument", "unknown mode", "not supported": invalid enum-like argument errors explained — this error's family across 19 libraries.

Related errors


AI-assisted analysis of symfony/routing@83fa223250 (2026-09-14). Data as JSON: /api/errors/b0fda149dd420e66. Report an issue: GitHub.

Appendix: source

Thrown at Requirement/EnumRequirement.php:29

namespace Symfony\Component\Routing\Requirement;

use Symfony\Component\Routing\Exception\InvalidArgumentException;

final class EnumRequirement implements \Stringable
{
    private string $requirement;

    /**
     * @template T of \BackedEnum
     *
     * @param class-string<T>|list<T> $cases
     */
    public function __construct(string|array $cases = [])
    {
        if (\is_string($cases)) {
            if (!is_subclass_of($cases, \BackedEnum::class, true)) {
                throw new InvalidArgumentException(\sprintf('"%s" is not a "BackedEnum" class.', $cases));
            }

            $cases = $cases::cases();
        } else {
            $class = null;

            foreach ($cases as $case) {
                if (!$case instanceof \BackedEnum) {
                    throw new InvalidArgumentException(\sprintf('Case must be a "BackedEnum" instance, "%s" given.', get_debug_type($case)));
                }

                $class ??= $case::class;

                if (!$case instanceof $class) {
                    throw new InvalidArgumentException(\sprintf('"%s::%s" is not a case of "%s".', get_debug_type($case), $case->name, $class));
                }
            }
        }

View on GitHub (pinned to 83fa223250)