{"record":{"id":"fd745a5c3b93fc32","repo":"passbolt/passbolt_api","slug":"no-user-provided-the-metadata-could-not-be-encrypted-for-fd745a","errorCode":null,"errorMessage":"No user provided. The metadata could not be encrypted for permission id: {0}.","messagePattern":"No user provided\\. The metadata could not be encrypted for permission id: (.+?)\\.","errorType":"exception","errorClass":"InternalErrorException","httpStatus":500,"severity":"error","filePath":"plugins/PassboltCe/Metadata/src/Service/Migration/MigrateAllV4ResourcesToV5Service.php","lineNumber":162,"sourceCode":"\n    /**\n     * @param \\Passbolt\\Metadata\\Model\\Dto\\MetadataResourceDto $dto DTO.\n     * @param \\App\\Model\\Entity\\Resource $resource Resource entity.\n     * @return void\n     * @throws \\Cake\\Http\\Exception\\InternalErrorException When resource type mapping is does not exist.\n     */\n    private function migratePersonal(MetadataResourceDto $dto, Resource $resource): void\n    {\n        $metadataArray = $dto->getClearTextMetadata();\n\n        /** @var \\App\\Model\\Entity\\Permission $permission */\n        $permission = $resource->get('permissions')[0];\n        $user = $permission->user;\n\n        if (!isset($user)) {\n            $msg = __('No user provided.') . ' ';\n            $msg .= __('The metadata could not be encrypted for permission id: {0}.', $permission->id);\n            throw new InternalErrorException($msg);\n        }\n        if (!isset($user->gpgkey)) {\n            $msg = __('No OpenPGP key found for the user.') . ' ';\n            $msg .= __('The metadata could not be encrypted with the user id: {0}.', $user->id);\n            throw new InternalErrorException($msg);\n        }\n        try {\n            $gpg = OpenPGPBackendFactory::get();\n            $gpg->clearKeys();\n            $gpg = $this->setSignKeyWithServerKey($gpg);\n            $gpg = $this->setEncryptKeyWithUserKey($gpg, $user->gpgkey);\n            $metadataClearText = json_encode($metadataArray, JSON_THROW_ON_ERROR);\n            $metadataEncrypted = $gpg->encrypt($metadataClearText, true);\n        } catch (Exception $exception) {\n            $msg = $exception->getMessage() . ' ';\n            $msg .= __('The metadata could not be encrypted with the user id: {0}.', $user->id);\n            throw new InternalErrorException($msg, 500, $exception);\n        }","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltCe/Metadata/src/Service/Migration/MigrateAllV4ResourcesToV5Service.php#L144-L180","documentation":"Thrown in migratePersonal() when the resource's sole permission references a user that is not present (permission->user is null). The service needs a user's OpenPGP key to encrypt the resource metadata with a user key, so without a user it cannot proceed. The error aborts migration for that resource and is recorded in the result errors array.","triggerScenarios":"migrate() -> migratePersonal() on a resource with exactly one permission that is not a group permission, where the permission's aro_foreign_key points to a user that no longer exists (deleted user, hard-deleted row) so the Users.Gpgkeys contain returns null for it.","commonSituations":"Instances where users were deleted without reassigning ownership of their personal resources; referential integrity gaps after manual DB edits or restores; permissions left pointing at soft/hard-removed accounts.","solutions":["Reassign the permission to an existing active user, or delete the orphaned permission and re-create ownership, then re-run migration.","Delete the orphaned resource if it is no longer needed, then re-run migration.","Find orphaned permissions ahead of time: SELECT permissions rows whose aro_foreign_key is absent from users, and fix them before migrating.","Enable user retention (soft delete) or cleanup policies that reassign resources before removing users."],"exampleFix":"// before: permission aro_foreign_key = <deleted-user-id>\n// after: point it at an active user\nUPDATE permissions SET aro_foreign_key = '<active-user-id>' WHERE id = '<permission-id>';","handlingStrategy":"validation","validationCode":"// before migrating, find permissions pointing at missing users\n$orphanPerms = $permissionsTable->find()\n    ->leftJoinWith('Users')\n    ->where(['Permissions.aro' => 'User', 'Users.id IS' => null])\n    ->all();","typeGuard":"$user = $permission->user ?? null;\nif (!$user instanceof \\App\\Model\\Entity\\User) { skip($resource); }","tryCatchPattern":null,"preventionTips":["Never hard-delete users without reassigning their resources.","Audit permission->user joins before migration.","Use soft-delete for user removal.","Fix orphaned permissions flagged by the migration result promptly."],"tags":["migration","metadata","user-not-found","orphaned-data","encryption"],"backgroundTag":"user-not-found","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"}