{"record":{"id":"9d299f4e23e8e5be","repo":"passbolt/passbolt_api","slug":"could-not-save-the-user-data-please-try-again-later","errorCode":null,"errorMessage":"Could not save the user data. Please try again later.","messagePattern":"Could not save the user data\\. Please try again later\\.","errorType":"exception","errorClass":"Cake\\Http\\Exception\\InternalErrorException","httpStatus":500,"severity":"critical","filePath":"src/Controller/Users/UsersEditController.php","lineNumber":110,"sourceCode":"            throw new ValidationException(__('Could not validate user data.'), $user, $this->Users);\n        }\n        $this->Users->checkRules($user);\n        if ($user->getErrors()) {\n            throw new ValidationException(__('Could not validate user data.'), $user, $this->Users);\n        }\n        $isBeingDisabled = $wasDisabledNull && !is_null($user->disabled);\n\n        // Used when sending after update event\n        // We need entity's dirty state to know which column values has been changed.\n        $userEntityWithDirtyState = clone $user;\n\n        // Save\n        $saveOptions = [\n            'checkrules' => false,\n            AvatarsTable::FILESYSTEM_ADAPTER_OPTION => $filesystemAdapter,\n        ];\n        if (!$this->Users->save($user, $saveOptions)) {\n            throw new InternalErrorException('Could not save the user data. Please try again later.');\n        }\n\n        if ($isBeingDisabled) {\n            /** @var \\App\\Model\\Table\\SecretsTable $secretsTable */\n            $secretsTable = $this->fetchTable('Secrets');\n            $secretToExpire = $secretsTable->findByUserId($id)\n                ->select(['id', 'user_id', 'resource_id'])->all()->toArray();\n            $resourcesExpireResourcesService->expireResourcesForSecrets($secretToExpire);\n        }\n\n        // Get the updated version (ex. Role needs to be fetched again if role_id changed)\n        try {\n            /** @var \\App\\Model\\Entity\\User $user */\n            $user = $this->Users->findView($id, $this->User->role())->firstOrFail();\n        } catch (Exception $exception) {\n            $msg = __('Could not find the user data after save. Maybe it has been deleted in the meantime.');\n            throw new InternalErrorException($msg, 500, $exception);\n        }","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Controller/Users/UsersEditController.php#L92-L128","documentation":"InternalErrorException thrown when UsersTable::save() returns false while persisting the edited user (with 'checkrules' => false since rules were already checked). This indicates an unexpected persistence failure — database error, avatar filesystem write failure (the filesystem adapter option is passed to save), or a save() event/behavior aborting — not a client input problem.","triggerScenarios":"PUT /users/{id}.json where validation and rules passed but save() fails: DB unreachable/locked, avatar storage adapter cannot write, an attached model event (e.g. from a plugin) returns false, or a race deleted the row mid-request.","commonSituations":"Database down or credentials changed; disk full or wrong permissions on the avatar storage path; a plugin's Users event listener aborts saves; migrations out of date so a column is missing.","solutions":["Check server logs for the underlying CakePHP/database error accompanying the 500.","Verify database connectivity and that migrations are up to date (`ddev refresh` / passbolt migration status).","If avatars are enabled, check the avatar filesystem adapter's storage path permissions and free space.","Disable recently added plugins that hook into user save events and retry to isolate the aborting listener."],"exampleFix":"// server-side: ensure storage is writable before retrying the request\n// before\nsudo chown www-data:www-data /var/www/html/webroot/img/public/Avatar\n// after\nsudo chown -R www-data:www-data /var/www/html/webroot/img/public/Avatar && sudo -u www-data test -w /var/www/html/webroot/img/public/Avatar","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await api.editUser(id, data); } catch (e) { if (e.code === 500 && /Could not save the user data/.test(e.message)) { await sleep(1000); return retryWithBackoff(() => api.editUser(id, data), 3); } throw e; }","preventionTips":["Monitor server database health and migration status before bulk user operations.","Ensure avatar storage has free space and correct permissions.","Retry with backoff for transient 500s; alert on repeated failures instead of retrying forever."],"tags":["persistence","database","internal-error","http-500"],"backgroundTag":"database-write-failed","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}