{"record":{"id":"684a18cd3a4b9b80","repo":"passbolt/passbolt_api","slug":"the-supplied-email-notification-settings-are-not-valid","errorCode":null,"errorMessage":"The supplied email notification settings are not valid","messagePattern":"The supplied email notification settings are not valid","errorType":"validation","errorClass":"App\\Error\\Exception\\CustomValidationException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltCe/EmailNotificationSettings/src/Controller/NotificationOrgSettings/NotificationOrgSettingsPostController.php","lineNumber":85,"sourceCode":"        if ($this->User->role() !== Role::ADMIN) {\n            throw new ForbiddenException(__('You are not allowed to access this location.'));\n        }\n        if (!$this->request->is('json')) {\n            throw new BadRequestException(__('This is not a valid Ajax/Json request.'));\n        }\n\n        $data = $this->request->getData();\n\n        foreach ($data as $key => $value) {\n            $data[$key] = QueryStringComponent::normalizeBoolean($value);\n        }\n\n        $form = new EmailNotificationSettingsForm();\n\n        if (!$form->validate($data)) {\n            $errors = $form->getErrors();\n\n            throw new CustomValidationException(__('The supplied email notification settings are not valid'), $errors);\n        }\n\n        $data = EmailNotificationSettingsForm::formatFormDataToOrgSettings($data);\n\n        return Hash::expand($data);\n    }\n\n    /**\n     * Format the . delimited keys to snake_case\n     *\n     * @param array<string, mixed> $data The data to Format\n     * @return array<string, mixed> the formatted array\n     */\n    private function _formatForOutput(array $data): array\n    {\n        $output = [];\n\n        foreach ($data as $key => $value) {","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltCe/EmailNotificationSettings/src/Controller/NotificationOrgSettings/NotificationOrgSettingsPostController.php#L67-L103","documentation":"A CustomValidationException thrown when EmailNotificationSettingsForm::validate() fails on the posted data. The payload reached the controller and passed role/JSON checks, but one or more fields did not satisfy the form's validation rules; the exception carries the per-field errors in its body.","triggerScenarios":"POST to /email-notification-settings/org-settings with data keys that are not valid notification settings, or values that fail boolean/normalization validation after QueryStringComponent::normalizeBoolean (e.g. unknown setting names, non-boolean values for known settings).","commonSituations":"Typo in a setting key (e.g. 'sendAdminUserSetupCompleted' vs the exact form field name); sending strings like 'yes'/'no' instead of booleans; sending nested/expanded structures the flat form does not expect; API version changes renaming settings.","solutions":["Inspect the 'errors' payload of the CustomValidationException response to identify which fields failed.","Send only known EmailNotificationSettingsForm field keys with boolean values (true/false or 0/1).","Read the form's validation schema (EmailNotificationSettingsForm) to confirm exact field names before posting.","Update client-side settings payload to match the current passbolt version's expected setting names."],"exampleFix":"// before\n{\"send_admin_user_setup_complete\": \"yes\", \"unknown_setting\": true}\n\n// after\n{\"send_admin_user_setup_complete\": true}","handlingStrategy":"validation","validationCode":"$form = new EmailNotificationSettingsForm();\n$errors = $form->validate($data) ? [] : $form->getErrors();\nif ($errors) {\n    // fix payload before calling the controller\n    return $errors;\n}","typeGuard":"function isBoolSettingValue($v): bool { return is_bool($v) || in_array($v, [0, 1, '0', '1', 'true', 'false'], true); }","tryCatchPattern":"try {\n    $response = $client->postEmailNotificationOrgSettings($data);\n} catch (CustomValidationException $e) {\n    $fieldErrors = $e->getErrors(); // inspect and correct the payload\n}","preventionTips":["Mirror the exact field names from EmailNotificationSettingsForm in the client payload.","Send only boolean-valued settings (true/false, 0/1).","Validate the payload with the same form class on the client side before posting.","Keep client payloads updated when upgrading passbolt since setting names can change."],"tags":["validation","form-validation","settings","controller"],"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"}