{"record":{"id":"f3cf9814c00e51e3","repo":"passbolt/passbolt_api","slug":"invalid-request-you-cannot-opt-out","errorCode":null,"errorMessage":"Invalid request. You cannot opt-out.","messagePattern":"Invalid request\\. You cannot opt-out\\.","errorType":"validation","errorClass":"CustomValidationException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltEe/AccountRecovery/src/Service/AccountRecoveryUserSettings/AccountRecoveryUserSettingsSetService.php","lineNumber":166,"sourceCode":"            return $this->AccountRecoveryUserSettings->buildAndValidateEntity($this->uac, $status);\n        } catch (ValidationException $exception) {\n            throw new CustomValidationException($exception->getMessage(), [\n                'account_recovery_user_setting' => $exception->getErrors(),\n            ]);\n        }\n    }\n\n    /**\n     * Check that the user selected setting makes sense as per select org policy\n     *\n     * @param \\Passbolt\\AccountRecovery\\Model\\Entity\\AccountRecoveryUserSetting $setting entity\n     * @throws \\Cake\\Http\\Exception\\BadRequestException if user rejects and policy is mandatory\n     * @return void\n     */\n    protected function assertRules(AccountRecoveryUserSetting $setting): void\n    {\n        if ($this->organizationPolicy->isMandatory() && !$setting->isApproved()) {\n            throw new CustomValidationException(__('Invalid request. You cannot opt-out.'), [\n                'account_recovery_user_setting' => [\n                    'status' => [\n                        'isMandatoryRule' => __('The status must be set to approved.'),\n                    ],\n                ],\n            ]);\n        }\n\n        if (!$setting->isApproved() && ($this->isPrivateKeyProvided() || $this->arePasswordsProvided())) {\n            throw new CustomValidationException(__('Invalid request. You cannot both opt-out and provide backup.'), [\n                'account_recovery_user_setting' => [\n                    'status' => [\n                        'isMatchingData' => __('The status must be set to approved.'),\n                    ],\n                ],\n            ]);\n        }\n","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/AccountRecovery/src/Service/AccountRecoveryUserSettings/AccountRecoveryUserSettingsSetService.php#L148-L184","documentation":"assertRules() throws this CustomValidationException when the organization policy is mandatory and the resulting setting is not approved. Unlike the plain BadRequest variant, it carries structured errors (status.isMandatoryRule) for form rendering.","triggerScenarios":"Any submitted setting that ends up non-approved (rejected, or other non-approved status) while organization policy is mandatory; same family as error 542 but raised through the entity-rule path of patchEntity.","commonSituations":"Old client versions caching a non-mandatory policy and sending opt-out; users bypassing the UI with direct API calls; org policy changed to mandatory mid-flow.","solutions":["Re-fetch the organization policy before submitting and force status=approved when mandatory","Update/refresh clients so they honor the current policy","If opt-out is legitimately required, change the organization policy first"],"exampleFix":"// before\nconst status = 'rejected';\n// after\nconst status = organizationPolicy.isMandatory ? 'approved' : 'rejected';","handlingStrategy":"validation","validationCode":"if (orgPolicy.isMandatory && submittedStatus !== 'approved') throw new Error('policy is mandatory: status must be approved');","typeGuard":"const isCompliant = (policy, s) => !policy.isMandatory || s === 'approved';","tryCatchPattern":"try { await setSettings(data); } catch (e) { if (e.body?.account_recovery_user_setting?.status?.isMandatoryRule) { /* force approved */ } }","preventionTips":["Derive allowed statuses from the live org policy, not cached values","Re-check policy after admins change it","Add client-side rule mirroring isMandatoryRule"],"tags":["validation","policy","account-recovery"],"backgroundTag":"schema-validation-failed","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"}