{"id":"5d106bf2d7c8705e","repo":"laravel/framework","slug":"the-provided-class-must-extend-collection-class-5d106b","errorCode":null,"errorMessage":"The provided class must extend [{Collection::class}].","messagePattern":"The provided class must extend \\[(.+?)\\]\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Illuminate/Database/Eloquent/Casts/AsEncryptedCollection.php","lineNumber":36,"sourceCode":"     * @return \\Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes<\\Illuminate\\Support\\Collection<array-key, mixed>, iterable>\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function castUsing(array $arguments)\n    {\n        return new class($arguments) implements CastsAttributes\n        {\n            public function __construct(protected array $arguments)\n            {\n                $this->arguments = array_pad(array_values($this->arguments), 2, '');\n            }\n\n            public function get($model, $key, $value, $attributes)\n            {\n                $collectionClass = empty($this->arguments[0]) ? Collection::class : $this->arguments[0];\n\n                if (! is_a($collectionClass, Collection::class, true)) {\n                    throw new InvalidArgumentException('The provided class must extend ['.Collection::class.'].');\n                }\n\n                if (! isset($attributes[$key])) {\n                    return null;\n                }\n\n                $instance = new $collectionClass(Json::decode(Crypt::decryptString($attributes[$key])));\n\n                if (! isset($this->arguments[1]) || ! $this->arguments[1]) {\n                    return $instance;\n                }\n\n                if (is_string($this->arguments[1])) {\n                    $this->arguments[1] = Str::parseCallback($this->arguments[1]);\n                }\n\n                return is_callable($this->arguments[1])\n                    ? $instance->map($this->arguments[1])","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/laravel/framework/blob/bd6b5437e6ad87bb49f9b426724f07a9f64e9683/src/Illuminate/Database/Eloquent/Casts/AsEncryptedCollection.php#L18-L54","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before\nprotected $casts = [\n    'notes' => AsEncryptedCollection::class.':'.NoteList::class,\n];\n\n// after\nclass NoteList extends \\Illuminate\\Support\\Collection {}\n// or simply:\nprotected $casts = ['notes' => AsEncryptedCollection::class];","handlingStrategy":"validation","validationCode":"use Illuminate\\Support\\Collection;\n$cls = \\App\\Support\\SecureNotes::class;\nif (! is_a($cls, Collection::class, true)) {\n    throw new \\LogicException(\"{$cls} must extend \".Collection::class);\n}","typeGuard":"function isEncryptedCollectionSafe(string $class): bool\n{\n    return is_a($class, \\Illuminate\\Support\\Collection::class, true);\n}","tryCatchPattern":"try {\n    return $model->notes;\n} catch (\\InvalidArgumentException $e) {\n    if (str_contains($e->getMessage(), 'must extend [')) {\n        report(\"AsEncryptedCollection cast misconfigured for \" . get_class($model));\n    }\n    throw $e;\n}","preventionTips":["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."],"tags":["eloquent","cast","collection","encryption","type-error"],"analyzedSha":"bd6b5437e6ad87bb49f9b426724f07a9f64e9683","analyzedAt":"2026-08-06T00:28:32.783Z","schemaVersion":2}