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

  1. Pass an instance of the exact enum the cast expects (e.g. Status::Active, not UserStatus::Active).
  2. Update the cast to reference the correct enum class string.
  3. 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

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


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)