{"id":"a892d5115c296943","repo":"laravel/framework","slug":"the-cast-object-for-the-attribute-attribute-mus","errorCode":null,"errorMessage":"The cast object for the {$attribute} attribute must implement Stringable.","messagePattern":"The cast object for the (.+?) attribute must implement Stringable\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php","lineNumber":821,"sourceCode":"\n    /**\n     * Ensure that the given casts are strings.\n     *\n     * @param  array  $casts\n     * @return array\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function ensureCastsAreStringValues($casts)\n    {\n        foreach ($casts as $attribute => $cast) {\n            $casts[$attribute] = match (true) {\n                is_object($cast) => value(function () use ($cast, $attribute) {\n                    if ($cast instanceof Stringable) {\n                        return (string) $cast;\n                    }\n\n                    throw new InvalidArgumentException(\n                        \"The cast object for the {$attribute} attribute must implement Stringable.\"\n                    );\n                }),\n                is_array($cast) => value(function () use ($cast) {\n                    if (count($cast) === 1) {\n                        return $cast[0];\n                    }\n\n                    [$cast, $arguments] = [array_shift($cast), $cast];\n\n                    return $cast.':'.implode(',', $arguments);\n                }),\n                default => $cast,\n            };\n        }\n\n        return $casts;\n    }","sourceCodeStart":803,"sourceCodeEnd":839,"githubUrl":"https://github.com/laravel/framework/blob/bd6b5437e6ad87bb49f9b426724f07a9f64e9683/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php#L803-L839","documentation":"mergeCasts()/ensureCastsAreStringValues() accepts object-based casts but they must implement Stringable so the framework can serialize them into the casts array (which holds string cast definitions). Non-Stringable objects cannot be expressed as a cast string.","triggerScenarios":"Calling $model->mergeCasts(['payload' => $someObject]) or assigning $casts[] = $someObject at runtime where $someObject is a plain stdClass or a class without __toString(). Also from passing a custom caster object that was meant to be a class string.","commonSituations":"Confusing a CastsAttributes instance (which should be passed as a class string or via ::class) with an object; passing a value object instead of a castable class string; third-party package that returns plain objects as casts.","solutions":["Implement the Stringable (or simply __toString()) interface on the cast object so it can render to a cast string.","Pass the class name string (e.g. MyCaster::class) instead of an instance when registering the cast.","Implement Castable on the class and use its ::class string in $casts."],"exampleFix":"// before\n$model->mergeCasts(['settings' => new PlainObject]);\n\n// after\nclass SettingsCast implements \\Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes, \\Stringable\n{\n    public function __toString(): string { return SettingsCast::class; }\n}\n$model->mergeCasts(['settings' => new SettingsCast]);","handlingStrategy":"type-guard","validationCode":"foreach ($castsToMerge as $attr => $cast) {\n    if (is_object($cast) && ! ($cast instanceof \\Stringable)) {\n        throw new \\InvalidArgumentException(\"{$attr} cast object must implement Stringable\");\n    }\n}\n$model->mergeCasts($castsToMerge);","typeGuard":"function castObjectIsValid(mixed $cast): bool\n{\n    return ! is_object($cast) || $cast instanceof \\Stringable;\n}","tryCatchPattern":"try {\n    $model->mergeCasts($casts);\n} catch (\\InvalidArgumentException $e) {\n    if (str_contains($e->getMessage(), 'must implement Stringable')) {\n        report('Non-Stringable cast object passed');\n    }\n    throw $e;\n}","preventionTips":["Prefer passing class-string (Cast::class) for custom casts rather than instances.","Implement Stringable (__toString) on any caster you intend to register as an object.","Use Castable classes for parameterized casts."],"tags":["eloquent","cast","type-error","stringable"],"analyzedSha":"bd6b5437e6ad87bb49f9b426724f07a9f64e9683","analyzedAt":"2026-08-06T00:28:32.783Z","schemaVersion":2}