twigphp/Twig · error · RuntimeError
Enum " " does not exist.
Error message
Enum "%s" does not exist.
What it means
Thrown by CoreExtension::enumCases, which backs Twig's `enum_cases` function. It validates its argument with enum_exists() and throws this RuntimeError when the given class string is not an existing enum — either the class does not exist at all or it exists but is a regular class/interface, not an enum.
Solutions
- Pass the correct fully-qualified enum class name (e.g. 'App\Enum\Status'), verifying it with var_dump(enum_exists('App\Enum\Status'))
- Run composer dump-autoload if the class exists but is not autoloaded
- Check the argument is a string, not a variable holding an instance — for instances, pass the FQCN or use `enum_cases(class-string)`
- Require PHP >= 8.1 and make the referenced type actually a backed/unit enum
Example fix
// before (Twig)
{% for case in enum_cases('Status') %}...{% endfor %}
// after
{% for case in enum_cases('App\\Enum\\Status') %}...{% endfor %} Defensive patterns
Strategy: type-guard
Validate before calling
if (!\is_string($enum) || !\enum_exists($enum)) {
throw new \InvalidArgumentException("Not a valid enum class: " . print_r($enum, true));
} Type guard
function isValidEnumClass(mixed $class): bool {
return \is_string($class) && \enum_exists($class);
} Try / catch
try {
$cases = $twig->render('t.html', ['enumClass' => $enumClass]);
} catch (\Twig\Error\RuntimeError $e) {
if (str_contains($e->getMessage(), 'does not exist')) {
// fall back to a hardcoded case list or log misconfiguration
} else { throw $e; }
} Prevention
- Always pass fully-qualified class-name strings ('App\Enum\Status') into enum_cases
- Run composer dump-autoload after adding/moving enums
- Pin PHP >= 8.1 where enums exist and add a static analysis rule banning non-enum class strings
- Keep enum FQCNs in PHP constants shared between templates and code instead of inline strings
When it happens
Trigger: Calling `enum_cases('App\Status')` in a template where the FQCN is wrong (missing namespace, typo, leading backslash handling), the enum class has not been autoloaded, or a non-enum class is passed. Also when passing a non-string (e.g. an object) that stringifies incorrectly.
Common situations: Refactoring/moving an enum without updating the template string; using a short class name without namespace; autoloading misconfiguration (composer dump-autoload not run); passing a class that is an enum in newer PHP but a class in older versions of your codebase; PHP < 8.1 environments where enums do not exist.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- " " is not an enum.
- The first argument of the "enum_cases" function must be the…
- The "html_classes" function argument
- Unknown attribute type
- Trimming side must be "left", "right" or "both".
AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13).
Data as JSON: /api/errors/c2407570a4f70a92.
Report an issue: GitHub.
Appendix: source
Thrown at src/Extension/CoreExtension.php:1633
return '';
}
}
/**
* Returns the list of cases of the enum.
*
* @template T of \UnitEnum
*
* @param class-string<T> $enum
*
* @return list<T>
*
* @internal
*/
public static function enumCases(string $enum): array
{
if (!enum_exists($enum)) {
throw new RuntimeError(\sprintf('Enum "%s" does not exist.', $enum));
}
return $enum::cases();
}
/**
* Provides the ability to access enums by their class names.
*
* @template T of \UnitEnum
*
* @param class-string<T> $enum
*
* @return T
*
* @internal
*/
public static function enum(string $enum): \UnitEnum
{View on GitHub (pinned to a414c3a491)