{"id":"f1e51384f08e8a4e","repo":"laravel/framework","slug":"user-must-implement-canresetpassword-interface","errorCode":null,"errorMessage":"User must implement CanResetPassword interface.","messagePattern":"User must implement CanResetPassword interface\\.","errorType":"exception","errorClass":"UnexpectedValueException","httpStatus":null,"severity":"error","filePath":"src/Illuminate/Auth/Passwords/PasswordBroker.php","lineNumber":183,"sourceCode":"        return $user;\n    }\n\n    /**\n     * Get the user for the given credentials.\n     *\n     * @param  array  $credentials\n     * @return \\Illuminate\\Contracts\\Auth\\CanResetPassword|null\n     *\n     * @throws \\UnexpectedValueException\n     */\n    public function getUser(#[\\SensitiveParameter] array $credentials)\n    {\n        $credentials = Arr::except($credentials, ['token']);\n\n        $user = $this->users->retrieveByCredentials($credentials);\n\n        if ($user && ! $user instanceof CanResetPasswordContract) {\n            throw new UnexpectedValueException('User must implement CanResetPassword interface.');\n        }\n\n        return $user;\n    }\n\n    /**\n     * Create a new password reset token for the given user.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\CanResetPassword  $user\n     * @return string\n     */\n    public function createToken(CanResetPasswordContract $user)\n    {\n        return $this->tokens->create($user);\n    }\n\n    /**\n     * Delete password reset tokens of the given user.","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/laravel/framework/blob/bd6b5437e6ad87bb49f9b426724f07a9f64e9683/src/Illuminate/Auth/Passwords/PasswordBroker.php#L165-L201","documentation":"Thrown by PasswordBroker::getUser() when the user retrieved by credentials does not implement Illuminate\\Contracts\\Auth\\CanResetPassword. The broker needs this contract to call sendPasswordResetNotification() and to delete/store reset tokens.","triggerScenarios":"Calling Password::broker()->sendResetLink([...]) where the matched User model lacks the CanResetPassword implementation (and the CanResetPassword trait that wires getEmailForPasswordReset() and sendPasswordResetNotification()).","commonSituations":"A custom User model that extends a base other than Illuminate\\Foundation\\Auth\\User; removed the Notifiable + CanResetPassword traits; switched to a non-Eloquent user provider whose model is a plain stdClass.","solutions":["Make the User model implement Illuminate\\Contracts\\Auth\\CanResetPassword and use the Illuminate\\Foundation\\Auth\\CanResetPassword trait (and Notifiable for the reset notification).","If using a custom model, implement getEmailForPasswordReset() and sendPasswordResetNotification() manually.","Ensure the provider's 'model' config points at the correct class implementing the contract.","Add a static check in tests: assertTrue(is_subclass_of(User::class, CanResetPassword::class))."],"exampleFix":"// before\nuse Illuminate\\Foundation\\Auth\\User as Authenticatable;\n\nclass User extends Authenticatable\n{\n    // missing CanResetPassword trait\n}\n\n// after\nuse Illuminate\\Foundation\\Auth\\User as Authenticatable;\nuse Illuminate\\Notifications\\Notifiable;\n\nclass User extends Authenticatable\n{\n    use Notifiable; // provides sendPasswordResetNotification\n    // Authenticatable already uses CanResetPassword trait\n}","handlingStrategy":"type-guard","validationCode":"$model = config('auth.providers.users.model');\nif (! is_subclass_of($model, \\Illuminate\\Contracts\\Auth\\CanResetPassword::class)) {\n    throw new RuntimeException(\"User model [{$model}] must implement CanResetPassword.\");\n}","typeGuard":"function userImplementsCanResetPassword(string $modelClass): bool\n{\n    return is_subclass_of($modelClass, \\Illuminate\\Contracts\\Auth\\CanResetPassword::class);\n}","tryCatchPattern":"try {\n    $status = Password::broker()->sendResetLink($credentials);\n} catch (\\UnexpectedValueException $e) {\n    // surface a config error: the User model is missing the contract/trait\n    report($e);\n}","preventionTips":["Extend Illuminate\\Foundation\\Auth\\User (or use the CanResetPassword + Notifiable traits) on custom models.","Add a static assertion in tests that the User model implements CanResetPassword.","Keep the providers.users.model config pointing at the class that implements the contract."],"tags":["authentication","password-reset","user-model","laravel"],"analyzedSha":"bd6b5437e6ad87bb49f9b426724f07a9f64e9683","analyzedAt":"2026-08-06T00:28:32.783Z","schemaVersion":2}