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
- Correct or remove the cast entry in $casts; verify the class string with class_exists().
- Fix the typo to a valid primitive (integer, float, decimal:N, datetime, json, boolean, string, etc.) or a real caster class.
- 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
- Reference cast classes with ::class, not string literals.
- Run composer dump-autoload after moving cast classes.
- Add a startup/console test that iterates every model's $casts and verifies each entry resolves.
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
- Could not verify the hashed value's configuration.
- Unable to find observer: {$class}
- The provided class must extend [{Collection::class}].
- The provided class must extend [{Collection::class}].
- The cast object for the {$attribute} attribute must implemen
AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06).
Data as JSON: /data/errors/9664fd90ac3c5e1b.json.
Report an issue: GitHub.