symfony/http-foundation · error · UnexpectedValueException
Parameter " " cannot be converted to enum
Error message
Parameter "%s" cannot be converted to enum:
What it means
ParameterBag::getEnum() casts a stored parameter to a backed enum via $class::from($value). When the value is not a valid backing value (ValueError) or of an incompatible type (TypeError), it wraps the failure in an UnexpectedValueException naming the parameter key, appending the original message and chaining the original exception.
Solutions
- Validate the stored value against $class::tryFrom($value) before calling getEnum and handle null
- Update the config/env value to one of the enum's backed values
- Catch UnexpectedValueException (previous is the ValueError/TypeError) and fall back to a default case
- Add the missing case to the enum if the new value is legitimate
Example fix
// before
$mode = $bag->getEnum('mode', Mode::class); // throws for 'staging'
// after
$mode = Mode::tryFrom((string) $bag->get('mode')) ?? Mode::Test; Defensive patterns
Strategy: try-catch
Validate before calling
$raw = $bag->get('mode');
if (null !== $raw && null === Mode::tryFrom((string) $raw) && null === Mode::tryFrom((int) $raw)) {
throw new \InvalidArgumentException("'mode' is not a backed value of ".Mode::class);
} Type guard
function isBackedBy(Mixed $v, string $enumClass): bool {
return is_subclass_of($enumClass, \BackedEnum::class) && null !== $enumClass::tryFrom(is_int($v) || is_string($v) ? $v : (string) $v);
} Try / catch
try {
$mode = $bag->getEnum('mode', Mode::class);
} catch (\UnexpectedValueException $e) {
// $e->getPrevious() is the ValueError/TypeError
$mode = Mode::Test;
} Prevention
- Prefer ::tryFrom() over ::from() when values come from user/config input
- Keep enum backed values and config files in sync (rename values together)
- Validate config against allowed values at application boot
- Chain the previous exception for diagnostics when wrapping
When it happens
Trigger: $bag->getEnum('mode', Mode::class) where the stored value is a string/int that no enum case backs (e.g. 'live' when only 'test'/'prod' exist), a wrong-typed value (array, object), or a null stored value with no default.
Common situations: Config file contains an enum string that was renamed or is not a backed case after adding new enum members; environment variable contains an unexpected token; PHP version/type drift making the value a non-scalar.
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
- Parameter value " " cannot be converted to "bool".
- Parameter value " " cannot be filtered.
- Invalid URI: Scheme is malformed.
- The "sameSite" parameter value is not valid.
- The following options are not supported
AI-assisted analysis of symfony/http-foundation@5aea19cd67 (2026-09-13).
Data as JSON: /api/errors/e285b640a94ef3d6.
Report an issue: GitHub.
Appendix: source
Thrown at ParameterBag.php:202
* @param class-string<T> $class
* @param ?T $default
*
* @return ?T
*
* @psalm-return ($default is null ? T|null : T)
*
* @throws UnexpectedValueException if the parameter value cannot be converted to an enum
*/
public function getEnum(string $key, string $class, ?\BackedEnum $default = null): ?\BackedEnum
{
if (null === $value = $this->get($key)) {
return $default;
}
try {
return $class::from($value);
} catch (\ValueError|\TypeError $e) {
throw new UnexpectedValueException(\sprintf('Parameter "%s" cannot be converted to enum: ', $key).$e->getMessage().'.', $e->getCode(), $e);
}
}
/**
* Filter key.
*
* @param int $filter FILTER_* constant
* @param int|array{flags?: int, options?: array|\Closure} $options Flags from FILTER_* constants, and a Closure when using FILTER_CALLBACK
*
* @see https://php.net/filter-var
*
* @throws UnexpectedValueException if the parameter value is a non-stringable object
* @throws UnexpectedValueException if the parameter value is invalid and \FILTER_NULL_ON_FAILURE is not set
*/
public function filter(string $key, mixed $default = null, int $filter = \FILTER_DEFAULT, mixed $options = []): mixed
{
$value = $this->get($key, $default);
View on GitHub (pinned to 5aea19cd67)