{"record":{"id":"a18654bd8016f99f","repo":"doctrine/instantiator","slug":"the-provided-class-s-is-an-enum-and-cannot-be","errorCode":null,"errorMessage":"The provided class \"%s\" is an enum, and cannot be instantiated","messagePattern":"The provided class \"(.+?)\" is an enum, and cannot be instantiated","errorType":"exception","errorClass":"Doctrine\\Instantiator\\Exception\\InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Exception/InvalidArgumentException.php","lineNumber":48,"sourceCode":"    }\n\n    /**\n     * @phpstan-param ReflectionClass<T> $reflectionClass\n     *\n     * @template T of object\n     */\n    public static function fromAbstractClass(ReflectionClass $reflectionClass): self\n    {\n        return new self(sprintf(\n            'The provided class \"%s\" is abstract, and cannot be instantiated',\n            $reflectionClass->getName(),\n        ));\n    }\n\n    public static function fromEnum(string $className): self\n    {\n        return new self(sprintf(\n            'The provided class \"%s\" is an enum, and cannot be instantiated',\n            $className,\n        ));\n    }\n}\n","sourceCodeStart":30,"sourceCodeEnd":53,"githubUrl":"https://github.com/doctrine/instantiator/blob/cbb879d6eea7ce605d95f4c455679df73ee682ea/src/Exception/InvalidArgumentException.php#L30-L53","documentation":"Thrown by fromEnum() when getReflectionClass() (src/Instantiator.php:147-148) detects via enum_exists($className, false) that the requested type is a PHP 8.1+ enum. Enums have no instances beyond their declared cases, so they cannot be constructor-less instantiated either; the library rejects them before any reflection work. The correct construction path is accessing a case (Suit::Hearts) or Suit::from($value), never the instantiator.","triggerScenarios":"Calling (new Instantiator())->instantiate(Suit::class) or any native enum FQCN on PHP >= 8.1. enum_exists() returns true at src/Instantiator.php:147 and fromEnum($className) throws. Common when generic factories, entity metadata walkers, or serializer/proxy generators pass every type name they discover into instantiate().","commonSituations":"A constants-holder class was migrated to a native enum during a PHP 8.1 upgrade while a config file or database table still lists it among instantiable classes; dependency graph walkers (ORM proxies, data-fixture loaders) enumerate all declared types including enums; hybrid code supporting both PHP < 8.1 (no enums) and >= 8.1 hits the enum path only in newer environments.","solutions":["Remove the enum from the set of names passed to instantiate() and construct it directly: use Suit::Hearts, Suit::cases(), or Suit::from($value).","Filter enum names out of dynamic type lists with enum_exists($name, false) before calling the instantiator.","If a config table or manifest still references the old class name after an enum migration, update those entries to point at the new usage pattern."],"exampleFix":"// before\n$suit = $instantiator->instantiate(Suit::class);\n// InvalidArgumentException: The provided class \"Suit\" is an enum,\n// and cannot be instantiated\n\n// after: enums are constructed from their cases, not instantiated\n$suit = Suit::Hearts;\n// or from a persisted value\n$suit = Suit::from($storedValue);","handlingStrategy":"validation","validationCode":"use function enum_exists;\n\nif (enum_exists($className, false)) {\n    throw new LogicException(sprintf('%s is an enum: construct it from a case or ::from().', $className));\n}\n\n$object = (new Instantiator())->instantiate($className);","typeGuard":"function isNonEnumClass(string $className): bool\n{\n    return class_exists($className) && ! enum_exists($className, false);\n}","tryCatchPattern":"use Doctrine\\Instantiator\\Exception\\InvalidArgumentException;\n\ntry {\n    $instance = $instantiator->instantiate($className);\n} catch (InvalidArgumentException $e) {\n    if (str_contains($e->getMessage(), 'is an enum')) {\n        // enums are value types: build them from cases, not instantiation\n        return $className::cases()[0];\n    }\n    throw $e;\n}","preventionTips":["When migrating constant classes to PHP 8.1 enums, also update every registry that listed the class as instantiable.","Filter dynamic type lists with enum_exists($name, false) before instantiating.","Treat enums as value objects in factories: map values via ::from() instead of constructor-bypassing instantiation."],"tags":["php","instantiation","enum","php-81"],"backgroundTag":"cannot-instantiate-enum","analyzedSha":"cbb879d6eea7ce605d95f4c455679df73ee682ea","analyzedAt":"2026-08-21T03:06:19.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T03:17:12.404Z"}