laravel/framework · error · InvalidArgumentException

The provided class must extend [Illuminate\Support\Collectio

Error message

The provided class must extend [Illuminate\Support\Collection].

What it means

Thrown by the AsCollection cast when the first argument (the custom collection class name) does not extend Illuminate\Support\Collection. The cast uses is_a() with allow_string=true to verify the class is a subclass before instantiating it; any class that is not a Collection descendant fails this check. This protects the cast from producing an object that lacks the Collection API the rest of Eloquent expects.

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 e0f6eb3518)

Solutions

  1. Verify the class passed as the first argument extends Illuminate\Support\Collection (use is_subclass_of($class, \Illuminate\Support\Collection::class)).
  2. Add the correct `use` import for the collection class and confirm the fully-qualified name in the cast definition.
  3. If you only need a base collection, drop the custom class argument and use AsCollection::class alone.
  4. If you need a custom class, make it `class MyCollection extends \Illuminate\Support\Collection`.

Example fix

// before
protected $casts = [
    'items' => AsCollection::class . ':' . App\Support\ItemBag::class, // ItemBag does not extend Collection
];

// after
class ItemBag extends \Illuminate\Support\Collection {}

protected $casts = [
    'items' => AsCollection::class . ':' . App\Support\ItemBag::class,
];
Defensive patterns

Strategy: validation

Validate before calling

use Illuminate\Support\Collection;

$collectionClass = App\Support\MyCollection::class; // candidate
if (! is_subclass_of($collectionClass, Collection::class)) {
    throw new \LogicException("{$collectionClass} must extend \\Illuminate\\Support\\Collection");
}
// safe to reference in cast string: AsCollection::class . ':' . $collectionClass

Type guard

function isValidCollectionClass(string $class): bool
{
    return class_exists($class) && is_subclass_of($class, \Illuminate\Support\Collection::class);
}

Prevention

When it happens

Trigger: Declaring a cast as AsCollection::class . ':' . SomeClass::class where SomeClass does not extend Illuminate\Support\Collection (e.g. a plain data object, a DTO, or a generic iterator). Also triggered by passing a fully-qualified class string that is misspelled or points to a non-Collection class. Reading the cast attribute (the get() method) runs the is_a() check.

Common situations: Using a custom collection class that was renamed or moved between Laravel versions; referencing a class whose namespace changed after an upgrade; passing an enum or interface name instead of a concrete Collection subclass; copy-pasting a cast from another project whose collection class does not exist here.

Related errors


AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11). Data as JSON: /api/errors/c49077abbd0a8f2c. Report an issue: GitHub.