laravel/framework · error · ValueError
Value [ ] is not of the expected enum type [ ].
Error message
Value [%s] is not of the expected enum type [%s].
What it means
Thrown by getStorableEnumValue() as a ValueError when a value being stored for an enum-cast attribute is not an instance of the expected enum class. Eloquent casts enum attributes by checking instanceof against the configured enum; on mismatch it raises ValueError with the var_export of the value and the expected enum FQN.
Solutions
- Pass an instance of the exact enum the cast expects (e.g. Status::Active, not UserStatus::Active).
- Update the cast to reference the correct enum class string.
- When accepting user input, convert the raw value to the enum case via Status::from($input) before assignment.
Example fix
// before protected $casts = ['status' => App\Enums\Status::class]; $user->status = App\Enums\UserStatus::Active; // ValueError // after $user->status = App\Enums\Status::Active;
Defensive patterns
Strategy: type-guard
Validate before calling
$expectedEnum = App\Enums\Status::class;
if ($value instanceof \BackedEnum || $value instanceof \UnitEnum) {
if (! $value instanceof $expectedEnum) {
throw new \UnexpectedValueException('Expected ' . $expectedEnum . ', got ' . get_class($value));
}
}
$model->status = $value; Type guard
function isExpectedEnum(\UnitEnum $value, string $expectedEnum): bool
{
return $value instanceof $expectedEnum;
} Try / catch
try {
$model->status = $input;
} catch (\ValueError $e) {
report($e);
$model->status = App\Enums\Status::default();
} Prevention
- Always pass enum *cases*, not scalars, to enum-cast attributes.
- Convert raw user input with Status::from($input) (or tryFrom) before assignment.
- Keep a single source of truth for each domain enum to avoid passing a same-named sibling enum.
When it happens
Trigger: Assigning a wrong-enum value to an enum-cast attribute (e.g. casting to App\Enums\Status but assigning a UserStatus case), or assigning a scalar to a typed enum attribute that expects a backed-enum case. Triggered on write/save when the cast serializes the value.
Common situations: Two enums with similar names (Status vs UserStatus) and passing the wrong one; assigning a string/int to an attribute cast to an enum instead of the enum case; a migration that changed which enum backs a column but old code still passes the previous enum.
Related errors
- Call to undefined cast
- Could not verify the hashed value's configuration.
- The cast object for the
- The provided class must extend…
- The provided class must extend…
AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11).
Data as JSON: /api/errors/e88dfbd7ac5aa9a8.
Report an issue: GitHub.
Appendix: source
Thrown at src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php:1333
{
return is_subclass_of($enumClass, BackedEnum::class)
? $enumClass::from($value)
: constant($enumClass.'::'.$value);
}
/**
* Get the storable value from the given enum.
*
* @param string $expectedEnum
* @param \UnitEnum $value
* @return string|int
*
* @throws \ValueError
*/
protected function getStorableEnumValue($expectedEnum, $value)
{
if (! $value instanceof $expectedEnum) {
throw new ValueError(sprintf('Value [%s] is not of the expected enum type [%s].', var_export($value, true), $expectedEnum));
}
return enum_value($value);
}
/**
* Get an array attribute with the given key and value set.
*
* @param string $path
* @param string $key
* @param mixed $value
* @return array
*/
protected function getArrayAttributeWithValue($path, $key, $value)
{
return tap($this->getArrayAttributeByKey($key), function (&$array) use ($path, $value) {
Arr::set($array, str_replace('->', '.', $path), $value);
});View on GitHub (pinned to e0f6eb3518)