laravel/framework · error · InvalidArgumentException
The provided class must extend [{Collection::class}].
Error message
The provided class must extend [{Collection::class}]. What it means
Identical guard to AsCollection but inside AsEncryptedCollection, which decrypts the column (via Crypt::decryptString) before building the collection. The configured class must still extend Illuminate\Support\Collection. Thrown from the cast's get() when the encrypted attribute is read.
Source
Thrown at src/Illuminate/Database/Eloquent/Casts/AsEncryptedCollection.php:36
* @return \Illuminate\Contracts\Database\Eloquent\CastsAttributes<\Illuminate\Support\Collection<array-key, mixed>, iterable>
*
* @throws \InvalidArgumentException
*/
public static function castUsing(array $arguments)
{
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)
{
$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 (! isset($attributes[$key])) {
return null;
}
$instance = new $collectionClass(Json::decode(Crypt::decryptString($attributes[$key])));
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
- Ensure the configured class extends Illuminate\Support\Collection.
- Drop the custom class argument and use AsEncryptedCollection::class or AsEncryptedCollection::of(Item::class).
- Add a boot-time assertion: abort_unless(is_a($cls, \Illuminate\Support\Collection::class, true), 500).
Example fix
// before
protected $casts = [
'notes' => AsEncryptedCollection::class.':'.NoteList::class,
];
// after
class NoteList extends \Illuminate\Support\Collection {}
// or simply:
protected $casts = ['notes' => AsEncryptedCollection::class]; Defensive patterns
Strategy: validation
Validate before calling
use Illuminate\Support\Collection;
$cls = \App\Support\SecureNotes::class;
if (! is_a($cls, Collection::class, true)) {
throw new \LogicException("{$cls} must extend ".Collection::class);
} Type guard
function isEncryptedCollectionSafe(string $class): bool
{
return is_a($class, \Illuminate\Support\Collection::class, true);
} Try / catch
try {
return $model->notes;
} catch (\InvalidArgumentException $e) {
if (str_contains($e->getMessage(), 'must extend [')) {
report("AsEncryptedCollection cast misconfigured for " . get_class($model));
}
throw $e;
} Prevention
- Treat the encrypted collection cast like AsCollection: same class constraint applies.
- Centralize encrypted-column casts in a trait or base model so the class string is defined once.
- Cover encrypted-attribute reads with a feature test that hydrates a real row.
When it happens
Trigger: Using 'secrets' => AsEncryptedCollection::using(SomeClass::class) where SomeClass is not a Collection subclass. Triggered on the first hydration/access of the encrypted attribute after the value is decrypted.
Common situations: Reusing a non-Collection DTO class intended for encrypted payloads; migrating from AsCollection to AsEncryptedCollection without re-checking that the collection class still extends the base; typos in the class string that resolve to an unrelated class.
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/5d106bf2d7c8705e.json.
Report an issue: GitHub.