{"record":{"id":"be0e0bd2c3356056","repo":"passbolt/passbolt_api","slug":"recovery-response-cannot-be-created-when-organization-policy","errorCode":null,"errorMessage":"Recovery response cannot be created when organization policy is disabled.","messagePattern":"Recovery response cannot be created when organization policy is disabled\\.","errorType":"http","errorClass":"Cake\\Http\\Exception\\BadRequestException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltEe/AccountRecovery/src/Service/AccountRecoveryResponses/AccountRecoveryResponsesCreateService.php","lineNumber":128,"sourceCode":"            ? static::RESPONSE_APPROVED_EVENT_NAME\n            : static::RESPONSE_REJECTED_EVENT_NAME;\n        $event = new Event($eventName, $responseEntity);\n        $this->AccountRecoveryResponses->getEventManager()->dispatch($event);\n\n        return $responseEntity;\n    }\n\n    /**\n     * @throws \\Cake\\Http\\Exception\\BadRequestException if organization policy is disabled\n     * @return void\n     */\n    public function assertPolicyIsEnabled(): void\n    {\n        $service = new AccountRecoveryOrganizationPolicyGetService();\n        $this->policy = $service->get();\n        if ($this->policy->isDisabled()) {\n            $msg = __('Recovery response cannot be created when organization policy is disabled.');\n            throw new BadRequestException($msg);\n        }\n    }\n\n    /**\n     * @throws \\App\\Error\\Exception\\CustomValidationException if the request id is not set, not valid, not found, is not pending\n     * @return \\Passbolt\\AccountRecovery\\Model\\Entity\\AccountRecoveryRequest\n     */\n    public function assertAndGetAssociatedRequest(): AccountRecoveryRequest\n    {\n        $requestId = $this->getData('account_recovery_request_id');\n        $msg = __('Could not validate response data.');\n\n        if (!isset($requestId) || empty($requestId) || !is_string($requestId)) {\n            throw new CustomValidationException($msg, [\n                'account_recovery_request_id' => [\n                    '_required' => 'The account recovery request id is required.',\n                ],\n            ]);","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/AccountRecovery/src/Service/AccountRecoveryResponses/AccountRecoveryResponsesCreateService.php#L110-L146","documentation":"Thrown as a BadRequestException when a client attempts to create an account recovery response while the organization-level account recovery policy is set to 'disabled'. The service explicitly blocks all recovery response creation because the feature is turned off organization-wide.","triggerScenarios":"POST to the account recovery responses endpoint while AccountRecoveryOrganizationPolicy is disabled; calling create() without first enabling the organization policy.","commonSituations":"Organization disabled account recovery after previously advertising it; clients with stale/recovery-enabled setups still posting responses; test environments where policy was never enabled.","solutions":["Enable the organization account recovery policy before creating responses (set the policy status via AccountRecoveryOrganizationSettings controller/service).","Remove the client call that posts the recovery response when the feature is disabled.","In API clients, check the policy state (GET /account-recovery/organization-policy) before posting a response."],"exampleFix":"// before (policy disabled, request fails)\n$post->post('/account-recovery/responses', $payload);\n// after\n$policy = $api->get('/account-recovery/organization-policy.json');\nif ($policy->data->status !== 'disabled') {\n    $post->post('/account-recovery/responses', $payload);\n}","handlingStrategy":"validation","validationCode":"$policy = (new AccountRecoveryOrganizationPolicyGetService())->get();\nif ($policy->isDisabled()) { throw new RuntimeException('Account recovery is disabled for this organization.'); }","typeGuard":"function accountRecoveryEnabled(?\\Passbolt\\AccountRecovery\\Model\\Entity\\AccountRecoveryOrganizationPolicy $p): bool {\n    return $p !== null && !$p->isDisabled();\n}","tryCatchPattern":"try {\n    $service->create($uac, $data);\n} catch (\\Cake\\Http\\Exception\\BadRequestException $e) {\n    if ($e->getMessage() === 'Recovery response cannot be created when organization policy is disabled.') {\n        // surface feature-disabled to user\n    }\n}","preventionTips":["Check the organization policy status before offering recovery flows in the UI.","Keep client feature flags in sync with the server policy.","Cover policy-disabled state in integration tests."],"tags":["account-recovery","bad-request","feature-disabled"],"backgroundTag":"feature-not-enabled","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}