passbolt/passbolt_api · error · Cake\Http\Exception\NotFoundException
The SCIM plugin is disabled.
Error message
The SCIM plugin is disabled.
What it means
After form validation, saveSettings() loads the single current scim_settings row. If no row exists (plugin effectively not configured) but the client supplied an $id to update, it throws NotFoundException with the (somewhat confusing) message 'The SCIM plugin is disabled.' — the record being updated does not exist.
Solutions
- Call GET /scim-settings first; if it returns no settings, create them with POST instead of PUT.
- Refresh the client's cached settings id after any deletion — the old UUID is permanently invalid.
- Enable/configure the SCIM plugin if it was expected to be configured on this instance.
Defensive patterns
Strategy: validation
Validate before calling
const settings = await (await fetch('/scim-settings.json')).json();
if (!settings.data) {
// no settings row exists: use POST create, never PUT
} Try / catch
try {
await api.put(`/scim-settings/${id}.json`, payload);
} catch (e) {
if (e.response?.status === 404) {
const { data } = await api.get('/scim-settings.json');
if (!data) await api.post('/scim-settings.json', payload); // create instead
}
} Prevention
- Re-fetch current settings before every update; never trust cached ids across sessions.
- Check existence with GET before deciding PUT vs POST.
- Handle concurrent admin deletes by treating 404 as 'create instead'.
When it happens
Trigger: PUT /scim-settings/<uuid> (or DELETE-style update flows) when the scim_settings table is empty — i.e., SCIM settings were never created or were already deleted.
Common situations: Client caching a settings id from a previous installation or after another admin deleted the settings; racing two admins where one deletes while the other updates; scripts replaying recorded PUT requests against a fresh instance.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Please delete previous settings before creating again.
- The resource type ` ` is not valid
- The SCIM setting does not exist.
- The uuid in the url doesn't match any known setting record.
- Could not validate the SCIM settings.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/568ea21da9182549.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/Scim/src/Service/ScimSetSettingsService.php:82
}
$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.'));
}
$currentValue = [];
$isDummyToken = $rawSecretToken === self::SCIM_SECRET_TOKEN_DUMMY;
if ($current) {
$currentValue = $this->decryptSettings($current);
$form->set('setting_id', Hash::get($currentValue, 'setting_id'));
if (!$form->getData('secret_token') || $isDummyToken) {
$form->set('secret_token', Hash::get($currentValue, 'secret_token'));
}
}
View on GitHub (pinned to 31c1bbc10f)