passbolt/passbolt_api · error · Passbolt\Scim\Exception\FormValidationException
Could not validate the SCIM settings.
Error message
Could not validate the SCIM settings.
What it means
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.
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.
Example fix
// before
{ "secret_token": "my-secret" }
// after
{ "setting_id": "5b06e2b6-... Defensive patterns
Strategy: validation
Validate before calling
function validateScimPayload(p) {
const uuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
if (!uuid.test(p.setting_id)) return 'setting_id must be a UUID';
if (!/^pb_[A-Za-z0-9_-]{43}$/.test(p.secret_token)) return 'secret_token must be pb_ + 43 chars';
return null;
} Try / catch
try {
await saveSettings(payload);
} catch (e) {
if (e.response?.status === 400 && e.response.data?.errors) {
console.error('Field errors:', e.response.data.errors); // fix per-field
}
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Could not validate the SCIM settings found in database.
- " " is not a valid search filter.
- " " is not a valid search filter. It is not a UTF8 string.
- " " is not a valid search filter. It should be between 1…
- " " is not a valid user filter.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/b133b92b07905269.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/Scim/src/Service/ScimSetSettingsService.php:71
* @throws \Exception
*/
public function saveSettings(UserAccessControl $uac, array $data, ?string $id = null): array
{
// Capture the raw plaintext token before form hashes it with bcrypt
$rawSecretToken = $data['secret_token'] ?? null;
$form = new ScimSettingsForm();
if ($id) {
if (!Validation::uuid($id)) {
throw new BadRequestException(__('The SCIM setting identifier should be a valid UUID.'));
}
$data['id'] = $id;
}
// Using this approach to avoid checking for setting_id duplicates on update
$validate = $id ? 'update' : 'extended';
if (!$form->execute($data, ['validate' => $validate])) {
throw new FormValidationException(
__('Could not validate the SCIM settings.'),
$form
);
}
/** @var \Passbolt\Scim\Model\Table\ScimSettingsTable $scimSettingsTable */
$scimSettingsTable = $this->fetchTable('Passbolt/Scim.ScimSettings');
/** @var \Passbolt\Scim\Model\Entity\ScimSetting|null $current */
$current = $scimSettingsTable->find()->first();
if (!$current && $id) {
throw new NotFoundException(__('The SCIM plugin is disabled.'));
}
if (!$id && $current) {
throw new BadRequestException(__('Please delete previous settings before creating again.'));
}
if ($current && $current->id !== $id) {
throw new NotFoundException(__('The uuid in the url doesn\'t match any known setting record.'));
}View on GitHub (pinned to 31c1bbc10f)