{"record":{"id":"b133b92b07905269","repo":"passbolt/passbolt_api","slug":"could-not-validate-the-scim-settings","errorCode":null,"errorMessage":"Could not validate the SCIM settings.","messagePattern":"Could not validate the SCIM settings\\.","errorType":"exception","errorClass":"Passbolt\\Scim\\Exception\\FormValidationException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltEe/Scim/src/Service/ScimSetSettingsService.php","lineNumber":71,"sourceCode":"     * @throws \\Exception\n     */\n    public function saveSettings(UserAccessControl $uac, array $data, ?string $id = null): array\n    {\n        // Capture the raw plaintext token before form hashes it with bcrypt\n        $rawSecretToken = $data['secret_token'] ?? null;\n\n        $form = new ScimSettingsForm();\n        if ($id) {\n            if (!Validation::uuid($id)) {\n                throw new BadRequestException(__('The SCIM setting identifier should be a valid UUID.'));\n            }\n            $data['id'] = $id;\n        }\n\n        // Using this approach to avoid checking for setting_id duplicates on update\n        $validate = $id ? 'update' : 'extended';\n        if (!$form->execute($data, ['validate' => $validate])) {\n            throw new FormValidationException(\n                __('Could not validate the SCIM settings.'),\n                $form\n            );\n        }\n\n        /** @var \\Passbolt\\Scim\\Model\\Table\\ScimSettingsTable $scimSettingsTable */\n        $scimSettingsTable = $this->fetchTable('Passbolt/Scim.ScimSettings');\n        /** @var \\Passbolt\\Scim\\Model\\Entity\\ScimSetting|null $current */\n        $current = $scimSettingsTable->find()->first();\n        if (!$current && $id) {\n            throw new NotFoundException(__('The SCIM plugin is disabled.'));\n        }\n        if (!$id && $current) {\n            throw new BadRequestException(__('Please delete previous settings before creating again.'));\n        }\n        if ($current && $current->id !== $id) {\n            throw new NotFoundException(__('The uuid in the url doesn\\'t match any known setting record.'));\n        }","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/Scim/src/Service/ScimSetSettingsService.php#L53-L89","documentation":"saveSettings() runs the request payload through ScimSettingsForm::execute() (using 'update' or 'extended' validation mode). If any field fails the form rules (setting_id format, secret_token shape, etc.), a FormValidationException with this generic message is thrown; the per-field errors are attached to the exception's form object.","triggerScenarios":"POST/PUT /scim-settings with a payload missing required fields (e.g. setting_id), an invalid secret_token format (must match the pb_ prefixed token pattern), or invalid setting_id/scim_user_id values.","commonSituations":"Provisioning scripts posting incomplete payloads, clients sending the bcrypt hash instead of a plaintext pb_ token, typos in field names, or integrations built against an older API schema before a required field was added.","solutions":["Read the form errors from the 400 response body (CakePHP forms serialize errors per field) and fix the reported field(s).","Ensure setting_id and scim_user_id are valid UUIDs and secret_token starts with 'pb_' followed by the expected base64url body (46 chars total, see SCIM_SECRET_TOKEN_PREFIX).","If updating, include the dummy token sentinel ('pb_0000...0') when the token should be kept unchanged instead of omitting or blanking secret_token.","Diff your payload against the ScimSettingsForm validation rules in plugins/PassboltEe/Scim/src/Form/Settings/ScimSettingsForm.php."],"exampleFix":"// before\n{ \"secret_token\": \"my-secret\" }\n// after\n{ \"setting_id\": \"5b06e2b6-...","handlingStrategy":"validation","validationCode":"function validateScimPayload(p) {\n  const uuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n  if (!uuid.test(p.setting_id)) return 'setting_id must be a UUID';\n  if (!/^pb_[A-Za-z0-9_-]{43}$/.test(p.secret_token)) return 'secret_token must be pb_ + 43 chars';\n  return null;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await saveSettings(payload);\n} catch (e) {\n  if (e.response?.status === 400 && e.response.data?.errors) {\n    console.error('Field errors:', e.response.data.errors); // fix per-field\n  }\n}","preventionTips":["Mirror ScimSettingsForm rules in the client before submitting.","Send the dummy token sentinel instead of blank/omitted secret_token when updating without rotation.","Keep setting_id/scim_user_id as real UUIDs from the users/settings tables.","Read the per-field errors in the 400 response body; the message alone is generic."],"tags":["scim","php","validation","cakephp-form"],"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"}