laravel/framework · error · InvalidArgumentException
The provided class must extend [{Collection::class}].
Error message
The provided class must extend [{Collection::class}]. What it means
Thrown by the AsCollection cast when the first argument (the collection class name) does not extend Illuminate\Support\Collection. The cast reads the column as JSON and instantiates the configured class, so it must be a real Collection subclass. The check happens in the cast's get() handler, i.e. whenever the casted attribute is accessed from a persisted model.
Source
Thrown at src/Illuminate/Database/Eloquent/Casts/AsCollection.php:41
return new class($arguments) implements CastsAttributes
{
public function __construct(protected array $arguments)
{
$this->arguments = array_pad(array_values($this->arguments), 2, '');
}
public function get($model, $key, $value, $attributes)
{
if (! isset($attributes[$key])) {
return;
}
$data = Json::decode($attributes[$key]);
$collectionClass = empty($this->arguments[0]) ? Collection::class : $this->arguments[0];
if (! is_a($collectionClass, Collection::class, true)) {
throw new InvalidArgumentException('The provided class must extend ['.Collection::class.'].');
}
if (! is_array($data)) {
return null;
}
$instance = new $collectionClass($data);
if (! isset($this->arguments[1]) || ! $this->arguments[1]) {
return $instance;
}
if (is_string($this->arguments[1])) {
$this->arguments[1] = Str::parseCallback($this->arguments[1]);
}
return is_callable($this->arguments[1])
? $instance->map($this->arguments[1])View on GitHub (pinned to bd6b5437e6)
Solutions
- Make the target class extend Illuminate\Support\Collection (e.g. class MyCollection extends \Illuminate\Support\Collection).
- If you do not need a custom collection type, drop the first argument: use AsCollection::class alone or AsCollection::of(Item::class).
- Verify with is_a($class, \Illuminate\Support\Collection::class, true) at boot before assigning the cast.
Example fix
// before
protected $casts = [
'tags' => AsCollection::class.':'.TagBag::class, // TagBag does not extend Collection
];
// after
protected $casts = [
'tags' => AsCollection::class, // default Illuminate\Support\Collection
];
// OR make TagBag extend Collection:
class TagBag extends \Illuminate\Support\Collection {} Defensive patterns
Strategy: validation
Validate before calling
use Illuminate\Support\Collection;
$cls = \App\Support\MyCollection::class;
if (! is_a($cls, Collection::class, true)) {
throw new \LogicException("{$cls} must extend ".Collection::class);
}
// only then use it in AsCollection::using($cls) Type guard
function isValidCollectionClass(string $class): bool
{
return is_a($class, \Illuminate\Support\Collection::class, true);
} Try / catch
try {
return $model->meta;
} catch (\InvalidArgumentException $e) {
if (str_contains($e->getMessage(), 'must extend [')) {
\Log::error('Bad AsCollection class on '.get_class($model), ['msg' => $e->getMessage()]);
}
throw $e;
} Prevention
- Always extend Illuminate\Support\Collection when creating custom collection types.
- Use AsCollection::of(Item::class) when you only need item mapping, not a custom collection class.
- Add a boot-time assertion in tests that checks every casted class string in $casts.
When it happens
Trigger: Declaring a cast like 'meta' => AsCollection::class.':'.SomeClass::class (or AsCollection::using(SomeClass::class, ...)) where SomeClass is a plain array/object wrapper or a custom class that does not extend Illuminate\Support\Collection. The exception fires on the first read of $model->meta after the row is hydrated from the database.
Common situations: Pointing the cast at a domain DTO or a generic Illuminate\Support\HigherOrderCollectionProxy by mistake; refactoring a custom collection but forgetting to extend the base Collection class; copy-pasting AsCollection::using from a doc sample that uses an arbitrary class string.
Related errors
- The provided class must extend [{Collection::class}].
- Unable to create query for collection with mixed types.
- The cast object for the {$attribute} attribute must implemen
- Value [%s] is not of the expected enum type [%s].
- Queueing collections with multiple model types is not suppor
AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06).
Data as JSON: /data/errors/d3b4a56291c6da48.json.
Report an issue: GitHub.