{"record":{"id":"c41e1ef0c7ae855e","repo":"passbolt/passbolt_api","slug":"invalid-record-set-responses-should-be-set-for-approved","errorCode":null,"errorMessage":"Invalid record set. Responses should be set for approved requests.","messagePattern":"Invalid record set\\. Responses should be set for approved requests\\.","errorType":"http","errorClass":"Cake\\Http\\Exception\\InternalErrorException","httpStatus":500,"severity":"critical","filePath":"plugins/PassboltEe/AccountRecovery/src/Service/AccountRecoveryRequests/AccountRecoveryRequestGetService.php","lineNumber":217,"sourceCode":"            'modified' => $requestEntity->modified,\n            'modified_by' => $requestEntity->modified_by,\n            'status' => $requestEntity->status,\n            // Not needed\n            //'armored_key' => $requestEntity->armored_key,\n        ];\n\n        if ($requestEntity->isApproved()) {\n            $errorMsg = 'Invalid record set. Responses should be set for approved requests.';\n\n            // There should be private key available\n            try {\n                /** @var \\Passbolt\\AccountRecovery\\Model\\Entity\\AccountRecoveryPrivateKey $privateKeyEntity */\n                $privateKeyEntity = $this->AccountRecoveryPrivateKeys->find()\n                    ->select('data')\n                    ->where(['user_id' => $requestEntity->user_id])\n                    ->firstOrFail();\n            } catch (RecordNotFoundException $exception) {\n                throw new InternalErrorException($errorMsg, 500, $exception);\n            }\n            $data['account_recovery_private_key']['data'] = $privateKeyEntity->data;\n\n            // There should be at least one response\n            $responses = $this->AccountRecoveryResponses->find()\n                ->select([\n                    'account_recovery_request_id',\n                    'status',\n                    'responder_foreign_model',\n                    'responder_foreign_key',\n                    'data',\n                ])\n                ->where(['account_recovery_request_id' => $requestEntity->id])\n                ->all()\n                ->toArray();\n            if (empty($responses)) {\n                throw new InternalErrorException($errorMsg);\n            }","sourceCodeStart":199,"sourceCodeEnd":235,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/AccountRecovery/src/Service/AccountRecoveryRequests/AccountRecoveryRequestGetService.php#L199-L235","documentation":"InternalErrorException (HTTP 500) from decorateResults: the request is approved, so an account_recovery_private_keys row containing the wrapped organization/private key data must exist for the requesting user, but the lookup returned nothing. This signals a data-integrity violation rather than a client mistake.","triggerScenarios":"decorateResults() on an approved request where AccountRecoveryPrivateKeys->find()->where(['user_id' => $requestEntity->user_id])->firstOrFail() finds no private key row for the user.","commonSituations":"Orphaned approved request after user data was deleted or a failed/partial enrollment; manual DB cleanup removed key rows; migration/upgrade left inconsistent account recovery data.","solutions":["Restore/recreate the user's account_recovery_private_keys row (re-run account recovery setup for that user)","Check DB integrity: user has account_recovery_user_settings + private key rows consistent with the approved request","Report to server admins — indicates corrupted account recovery state; inspect server logs for the underlying RecordNotFoundException"],"exampleFix":"// before\n// approved request but no account_recovery_private_keys row for user -> 500\n// after\nre-enroll user in account recovery so a private key row exists, or reject/delete the orphaned request","handlingStrategy":"try-catch","validationCode":"$hasKey = $this->AccountRecoveryPrivateKeys->exists(['user_id' => $userId]); if (!$hasKey && $request->isApproved()) { // surface data-integrity problem to admins before calling }","typeGuard":"null","tryCatchPattern":"try { $service->decorateResults($request); } catch (InternalErrorException $e) { logCriticalDataIntegrityIssue($request->id); alertAdmin(); }","preventionTips":["Never delete account_recovery_private_keys rows without cleaning dependent requests","Run data-integrity checks after migrations/upgrades","Treat 500s with this message as server bugs to report, not client issues"],"tags":["internal-error","data-integrity","account-recovery","missing-record"],"backgroundTag":"internal-invariant-violation","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"}