{"record":{"id":"d33920823c17052b","repo":"passbolt/passbolt_api","slug":"recovery-request-cannot-be-created-when-user-is-not-enrolled","errorCode":null,"errorMessage":"Recovery request cannot be created when user is not enrolled.","messagePattern":"Recovery request cannot be created when user is not enrolled\\.","errorType":"http","errorClass":"Cake\\Http\\Exception\\BadRequestException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltEe/AccountRecovery/src/Service/AccountRecoveryRequests/AccountRecoveryRequestCreateService.php","lineNumber":149,"sourceCode":"        $userId = $this->getData('user_id');\n        if (!Validation::uuid($userId)) {\n            throw new BadRequestException(__('The user identifier should be a valid UUID.'));\n        }\n\n        return $userId;\n    }\n\n    /**\n     * @throws \\Cake\\Http\\Exception\\BadRequestException if organization policy is disabled\n     * @return void\n     */\n    public function assertUserIsEnrolled(): void\n    {\n        $service = new AccountRecoveryUserSettingsGetService();\n        $userSettings = $service->get($this->getData('user_id'));\n        if (!isset($userSettings) || $userSettings->isRejected()) {\n            $msg = __('Recovery request cannot be created when user is not enrolled.');\n            throw new BadRequestException($msg);\n        }\n    }\n\n    /**\n     * Return the authentication from data if any\n     *\n     * @param string $userId the user uuid the token belongs to\n     * @throws \\Cake\\Http\\Exception\\BadRequestException if no authentication token was provided\n     * @throws \\Cake\\Http\\Exception\\BadRequestException if the authentication token is not a uuid\n     * @throws \\Cake\\Http\\Exception\\BadRequestException if the authentication token is expired or invalid\n     * @return \\App\\Model\\Entity\\AuthenticationToken\n     */\n    protected function getAndAssertToken(string $userId): AuthenticationToken\n    {\n        $token = $this->getData('authentication_token.token');\n        if (!isset($token)) {\n            throw new BadRequestException(__('An authentication token should be provided.'));\n        }","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/AccountRecovery/src/Service/AccountRecoveryRequests/AccountRecoveryRequestCreateService.php#L131-L167","documentation":"BadRequestException from assertUserIsEnrolled indicating the target user has no account recovery user settings or has explicitly rejected the program, so a recovery request cannot be created for them.","triggerScenarios":"POST /account-recovery/requests for a user whose account_recovery_user_settings row is absent, or whose status is 'rejected'.","commonSituations":"User never completed enrollment; organization policy was enabled after the user's setup so they were never enrolled; user disabled recovery in their settings; testing against a fresh user not run through account recovery setup.","solutions":["Complete account recovery enrollment for the user (account recovery setup flow)","Admin: verify the organization policy is enabled and user settings status is 'accepted'","If user rejected recovery intentionally, use the normal (non-recovery) login flow"],"exampleFix":"// before\n$userSettings->isRejected() === true // request refused\n// after\nrun account-recovery setup for user so settings status = 'accepted', then retry the request","handlingStrategy":"fallback","validationCode":"$settings = (new AccountRecoveryUserSettingsGetService())->get($userId); if ($settings === null || $settings->isRejected()) { // fall back to normal login flow }","typeGuard":"null","tryCatchPattern":"try { $service->create($data); } catch (BadRequestException $e) { if (str_contains($e->getMessage(), 'not enrolled')) { redirectToNormalRecoveryFlow(); } }","preventionTips":["Check enrollment status before initiating a recovery request","Ensure organization policy enablement runs the enrollment steps for existing users","Handle the 'rejected' setting state explicitly in the client UI"],"tags":["account-recovery","enrollment","state-validation","bad-request"],"backgroundTag":"invalid-state-transition","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T09:17:21.228Z"}