passbolt/passbolt_api · error · Cake\Http\Exception\NotFoundException
The uuid in the url doesn't match any known setting record.
Error message
The uuid in the url doesn't match any known setting record.
What it means
saveSettings() guards updates against stale identifiers: when a current settings row exists and the $id from the URL differs from $current->id, it throws NotFoundException because the UUID in the URL doesn't reference the existing record. Since only one row can exist, any other UUID is by definition unknown.
Solutions
- Re-fetch GET /scim-settings to obtain the current id and retry the PUT with it.
- If the settings were deleted and recreated, discard all cached ids and re-provision against the new record.
- If no update is intended, verify you are not accidentally treating a create call as an update by passing a stale $id parameter.
Example fix
// before
await api.put(`/scim-settings/${staleId}.json`, payload);
// after
const { data } = await api.get('/scim-settings.json');
await api.put(`/scim-settings/${data.id}.json`, payload); Defensive patterns
Strategy: validation
Validate before calling
const { data: current } = await api.get('/scim-settings.json');
if (current && current.id !== suppliedId) {
suppliedId = current.id; // refresh to the live record's UUID
} 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');
await api.put(`/scim-settings/${data.id}.json`, payload);
}
} Prevention
- Always resolve the id via GET /scim-settings immediately before PUT.
- Invalidate cached settings ids after delete/recreate operations.
- Never copy ids between environments — each install has its own row UUID.
When it happens
Trigger: PUT /scim-settings/<uuid> where <uuid> is a valid UUID but not the id of the single row in scim_settings — e.g. an id from a previous configuration or a fabricated UUID.
Common situations: Clients holding a stale id after settings were deleted and recreated (new row = new UUID); copy-pasted ids from docs or another environment; testing against a fresh database with ids from production.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- The SCIM plugin is disabled.
- Could not validate the SCIM settings.
- Could not validate the SCIM settings found in database.
- Please delete previous settings before creating again.
- Record not found
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/0619eb8ced04d15b.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/Scim/src/Service/ScimSetSettingsService.php:88
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'));
}
}
$settingsData = $form->getData();
$isTokenRotated = $this->isTokenRotated($rawSecretToken, $currentValue);
if (!$current || $isTokenRotated) {
$settingsData['expired'] = $this->computeExpiredDate();
} else {
$settingsData['expired'] = Hash::get($currentValue, 'expired');View on GitHub (pinned to 31c1bbc10f)