laravel/framework · error · InvalidCastException

Call to undefined cast [{$castType}] on column [{$column}] i

Error message

Call to undefined cast [{$castType}] on column [{$column}] in model [{$class}].

What it means

isClassCastable() resolves the cast string; if it is not a primitive type, not an enum, and the class does not exist, Eloquent throws InvalidCastException naming the model, column, and the bad cast type. This surfaces a clearly wrong $casts entry rather than failing later.

Source

Thrown at src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php:1802

    protected function isClassCastable($key)
    {
        $casts = $this->getCasts();

        if (! array_key_exists($key, $casts)) {
            return false;
        }

        $castType = $this->parseCasterClass($casts[$key]);

        if (in_array($castType, static::$primitiveCastTypes)) {
            return false;
        }

        if (class_exists($castType)) {
            return true;
        }

        throw new InvalidCastException($this->getModel(), $key, $castType);
    }

    /**
     * Determine if the given key is cast using an enum.
     *
     * @param  string  $key
     * @return bool
     */
    protected function isEnumCastable($key)
    {
        $casts = $this->getCasts();

        if (! array_key_exists($key, $casts)) {
            return false;
        }

        $castType = $casts[$key];

View on GitHub (pinned to bd6b5437e6)

Solutions

  1. Correct or remove the cast entry in $casts; verify the class string with class_exists().
  2. Fix the typo to a valid primitive (integer, float, decimal:N, datetime, json, boolean, string, etc.) or a real caster class.
  3. Run composer dump-autoload after moving cast classes between namespaces.

Example fix

// before
protected $casts = [
    'price' => 'App\Casts\MoneyCster', // typo / missing class
];

// after
protected $casts = [
    'price' => \App\Casts\MoneyCast::class,
];
Defensive patterns

Strategy: validation

Validate before calling

foreach ((new \ReflectionClass($model))->getDefaultProperties()['casts'] ?? [] as $col => $cast) {
    if (is_string($cast) && ! in_array($cast, ['int','integer','real','float','double','decimal:','bool','boolean','string','array','json','object','date','datetime','timestamp'])) {
        $cls = \Illuminate\Database\Eloquent\Model::parseCastClassName($cast) ?? $cast;
        if (! class_exists($cls) && ! enum_exists($cls)) {
            throw new \RuntimeException("Undefined cast '{$cast}' for '{$col}'");
        }
    }
}

Type guard

function castResolves(string $cast): bool
{
    $primitives = ['int','integer','real','float','double','bool','boolean','string','array','json','object','date','datetime','timestamp','encrypted','encrypted:array','encrypted:json','encrypted:collection','encrypted:object'];
    [$type] = explode(':', $cast . ':');
    if (in_array($type, $primitives)) return true;
    return class_exists($type) || enum_exists($type);
}

Try / catch

try {
    return $model->{$col};
} catch (\Illuminate\Database\Eloquent\InvalidCastException $e) {
    report('Invalid cast on ' . get_class($model) . '::' . $e->column . ' -> ' . $e->castType);
    throw $e;
}

Prevention

When it happens

Trigger: Declaring protected $casts = ['foo' => 'App\Missing\Caster'] (class does not exist), or a typo like 'datetimes' instead of 'datetime', or a deleted/renamed custom cast class still referenced.

Common situations: Refactor that moved/deleted a cast class without updating $casts; IDE auto-completing a wrong FQN; misspelled primitive cast names; namespaces changed during a package rename.

Related errors


AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06). Data as JSON: /data/errors/9664fd90ac3c5e1b.json. Report an issue: GitHub.