{"record":{"id":"ac848a54e1a34596","repo":"passbolt/passbolt_api","slug":"could-not-save-the-metadata-session-keys-please-try-again","errorCode":null,"errorMessage":"Could not save the metadata session keys, please try again later.","messagePattern":"Could not save the metadata session keys, please try again later\\.","errorType":"exception","errorClass":"InternalErrorException","httpStatus":500,"severity":"error","filePath":"plugins/PassboltCe/Metadata/src/Service/MetadataSessionKeyUpdateService.php","lineNumber":105,"sourceCode":"\n        $metadataSessionKey = $metadataSessionKeysTable->patchEntity(\n            $metadataSessionKey,\n            ['data' => $data['data']],\n            ['accessibleFields' => ['data' => true]]\n        );\n\n        try {\n            /** @var \\Passbolt\\Metadata\\Model\\Entity\\MetadataSessionKey $updatedEntity */\n            $updatedEntity = $metadataSessionKeysTable->saveOrFail($metadataSessionKey);\n        } catch (PersistenceFailedException $exception) { // @phpstan-ignore-line\n            // 400 openpgp data does not validate, for example it's not for the current user\n            throw new CustomValidationException(\n                __('The metadata session key could not be saved.'),\n                $exception->getEntity()->getErrors()\n            );\n        } catch (Exception $exception) {\n            // 500 entry could not be deleted because of some internal error\n            throw new InternalErrorException(\n                __('Could not save the metadata session keys, please try again later.'),\n                null,\n                $exception\n            );\n        }\n\n        return $updatedEntity;\n    }\n}\n","sourceCodeStart":87,"sourceCodeEnd":115,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltCe/Metadata/src/Service/MetadataSessionKeyUpdateService.php#L87-L115","documentation":"MetadataTypesSettingsAssertService wraps unexpected persistence exceptions. After the metadata session key entity fails to save for a reason other than validation, the service converts the underlying exception into a CakePHP InternalErrorException (HTTP 500) telling the client to retry later. It signals a server-side problem (DB, key server, crypto) rather than bad client input.","triggerScenarios":"Calling PUT/POST on the metadata session-key update endpoint (MetadataSessionKeyUpdateService::update) when Table::save() throws a non-validation exception, e.g. database connectivity loss, constraint violation not surfaced as entity errors, or a broken transaction.","commonSituations":"Database down or restarted mid-request; DB user lacking INSERT/UPDATE privileges on session_keys table; MySQL lock timeout under concurrent session-key rotations; Postgres/MySQL dialect issue after a migration.","solutions":["Check database connectivity and the app error logs for the wrapped original exception (chained as previous).","Retry the request after a short delay — the message explicitly asks the client to try again later.","Verify DB credentials/privileges for the passbolt user and that the metadata_session_keys table exists (run migrations).","Check for lock waits / long-running transactions on the session key table and reduce concurrent rotations."],"exampleFix":"// before\n$sessionKey = $this->MetadataSessionKeys->save($entity);\n// after\ntry {\n    $this->MetadataSessionKeys->getConnection()->begin();\n    $sessionKey = $this->MetadataSessionKeys->save($entity);\n    $this->MetadataSessionKeys->getConnection()->commit();\n} catch (\\Exception $e) {\n    $this->MetadataSessionKeys->getConnection()->rollback();\n    throw new InternalErrorException(__('Could not save the metadata session keys, please try again later.'), null, $e);\n}","handlingStrategy":"retry","validationCode":"// check DB reachable before calling the API\ntry {\n    \\Cake\\Datasource\\ConnectionManager::get('default')->query('SELECT 1');\n} catch (\\Exception $e) { /* abort: database unavailable */ }","typeGuard":null,"tryCatchPattern":"try {\n    $service->update($user, $data);\n} catch (\\Cake\\Http\\Exception\\InternalErrorException $e) {\n    // retry with backoff; inspect $e->getPrevious() for root cause\n    retry(fn() => $service->update($user, $data), attempts: 3, backoffMs: 500);\n}","preventionTips":["Monitor database health and lock waits before bulk session-key operations","Run migrations after upgrades so metadata_session_keys schema is current","Log the chained previous exception server-side for diagnosis"],"tags":["database","session-key","metadata","internal-error"],"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"}