passbolt/passbolt_api · error · Cake\Http\Exception\InternalErrorException

Could not find the user data after save. Maybe it has been…

Error message

Could not find the user data after save. Maybe it has been deleted in the meantime.

What it means

InternalErrorException raised when re-fetching the saved user via UsersTable::findView() immediately after a successful save, and the query throws or returns no row (firstOrFail). It signals the user record became unreadable/deleted between save and re-read — an inconsistency the API surfaces as a 500 with the original exception chained.

Solutions

  1. Verify the user still exists (GET /users/{id}.json) and re-issue the edit.
  2. Check server logs for the chained exception to see whether findView threw or simply found no row.
  3. Look for concurrent admin operations or cron jobs deleting users during edits.
  4. Review installed plugins that modify the Users findView query; disable suspects and retry.

Example fix

// before: editing a user concurrently being deleted
Promise.all([api.deleteUser(id), api.editUser(id, data)]);
// after
const user = await api.getUser(id);
if (user) await api.editUser(id, data);
Defensive patterns

Strategy: try-catch

Validate before calling

async function userExists(api, id) { try { return !!(await api.getUser(id)); } catch { return false; } }

Try / catch

try { await api.editUser(id, data); } catch (e) { if (e.code === 500 && /deleted in the meantime/.test(e.message)) { await refreshUserList(); } else { throw e; } }

Prevention

When it happens

Trigger: PUT /users/{id}.json completes save, then findView($id, role)->firstOrFail() fails: the user was deleted by a concurrent request, a findView event/behavior throws, or role-based visibility hides the row from the acting principal.

Common situations: Concurrent deletion by another admin during the edit; a plugin altering the findView query throwing an exception; permission/role changes mid-request (e.g. editor's own role changed) making the record invisible; DB replication lag on read replicas.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/871c715bfd3184fe. Report an issue: GitHub.

Appendix: source

Thrown at src/Controller/Users/UsersEditController.php:127

        if (!$this->Users->save($user, $saveOptions)) {
            throw new InternalErrorException('Could not save the user data. Please try again later.');
        }

        if ($isBeingDisabled) {
            /** @var \App\Model\Table\SecretsTable $secretsTable */
            $secretsTable = $this->fetchTable('Secrets');
            $secretToExpire = $secretsTable->findByUserId($id)
                ->select(['id', 'user_id', 'resource_id'])->all()->toArray();
            $resourcesExpireResourcesService->expireResourcesForSecrets($secretToExpire);
        }

        // Get the updated version (ex. Role needs to be fetched again if role_id changed)
        try {
            /** @var \App\Model\Entity\User $user */
            $user = $this->Users->findView($id, $this->User->role())->firstOrFail();
        } catch (Exception $exception) {
            $msg = __('Could not find the user data after save. Maybe it has been deleted in the meantime.');
            throw new InternalErrorException($msg, 500, $exception);
        }

        if ($isBeingDisabled) {
            $this->sendEmailOnUserDisable($user);
        }

        $this->sendAfterUpdateEvent($userEntityWithDirtyState);

        $this->success(__('The user has been updated successfully.'), $user);
    }

    /**
     * Validate if the user is authorized to edit the data
     *
     * @param array $data user data
     * @return void
     * @throws \Cake\Http\Exception\ForbiddenException if the user is not admin or not editing themselves
     * @throws \Cake\Http\Exception\ForbiddenException if the user is not admin and editing role

View on GitHub (pinned to 31c1bbc10f)