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

  1. Re-fetch GET /scim-settings to obtain the current id and retry the PUT with it.
  2. If the settings were deleted and recreated, discard all cached ids and re-provision against the new record.
  3. 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

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


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)