{"record":{"id":"1bdc5a6a16278673","repo":"passbolt/passbolt_api","slug":"the-account-recovery-request-response-is-invalid","errorCode":null,"errorMessage":"The account recovery request response is invalid.","messagePattern":"The account recovery request response is invalid\\.","errorType":"validation","errorClass":"ValidationException","httpStatus":422,"severity":"error","filePath":"plugins/PassboltEe/AccountRecovery/src/Model/Table/AccountRecoveryResponsesTable.php","lineNumber":263,"sourceCode":"            'modified_by' => $uac->getId(),\n        ]);\n\n        /** @var \\Passbolt\\AccountRecovery\\Model\\Entity\\AccountRecoveryResponse $responseEntity */\n        $responseEntity = $this->newEntity($data, [\n            'accessibleFields' => [\n                'account_recovery_request_id' => true,\n                'responder_foreign_key' => true,\n                'responder_foreign_model' => true,\n                'data' => true,\n                'status' => true,\n                'created_by' => true,\n                'modified_by' => true,\n            ],\n        ]);\n\n        if ($responseEntity->getErrors()) {\n            $msg = __('The account recovery request response is invalid.');\n            throw new ValidationException($msg, $responseEntity, $this);\n        }\n\n        return $responseEntity;\n    }\n\n    /**\n     * Delete all records where associated responses are deleted\n     *\n     * @param bool|null $dryRun false\n     * @return int of affected records\n     */\n    public function cleanupHardDeletedAccountRecoveryRequests(?bool $dryRun = false): int\n    {\n        return $this->cleanupHardDeleted('AccountRecoveryRequests', $dryRun);\n    }\n\n    /**\n     * Retrieves a list of cleanup methods (first-class callables) implemented by this table.","sourceCodeStart":245,"sourceCodeEnd":281,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/AccountRecovery/src/Model/Table/AccountRecoveryResponsesTable.php#L245-L281","documentation":"Thrown by AccountRecoveryResponsesTable::buildAndValidateEntity when the account recovery response entity fails validation rules defined on the table (status inList, responder foreign model, request association, etc.). The response entity containing the errors is attached to the exception.","triggerScenarios":"Creating a recovery response (POST /account-recovery/responses) with a status outside ['rejected','approved'], an invalid responder_foreign_model (only 'AccountRecoveryOrganizationKey' is allowed), a missing/unknown account_recovery_request_id, or a responder foreign key that does not match the model.","commonSituations":"Client submits a response before the organization recovery key is configured; missing required fields in the JSON payload; referencing a request UUID that does not exist; passing the wrong responder model name.","solutions":["Inspect the errors attached to the exception entity for the exact failing field","Ensure status is exactly 'approved' or 'rejected'","Ensure responder_foreign_model is 'AccountRecoveryOrganizationKey' with a valid matching foreign key","Verify the account_recovery_request_id references an existing pending request"],"exampleFix":"// before\n{\"status\": \"yes\", \"account_recovery_request_id\": \"<uuid>\"}\n// after\n{\"status\": \"approved\", \"account_recovery_request_id\": \"<uuid>\", \"responder_foreign_model\": \"AccountRecoveryOrganizationKey\"}","handlingStrategy":"validation","validationCode":"function validateResponsePayload(p) {\n  const errs = [];\n  if (!['approved','rejected'].includes(p.status)) errs.push('status');\n  if (!p.account_recovery_request_id) errs.push('account_recovery_request_id');\n  if (p.responder_foreign_model !== 'AccountRecoveryOrganizationKey') errs.push('responder_foreign_model');\n  return errs;\n}","typeGuard":"function isValidResponsePayload(p) {\n  return ['approved','rejected'].includes(p.status)\n    && typeof p.account_recovery_request_id === 'string'\n    && p.responder_foreign_model === 'AccountRecoveryOrganizationKey';\n}","tryCatchPattern":"try {\n  await api.createAccountRecoveryResponse(payload);\n} catch (e) {\n  const fieldErrors = e.body?.errors ?? {};\n  Object.entries(fieldErrors).forEach(([f, err]) => console.warn(f, err));\n}","preventionTips":["Verify the organization recovery key exists before submitting responses","Always include responder_foreign_model with value 'AccountRecoveryOrganizationKey'","Validate the request UUID exists via GET /account-recovery/requests first"],"tags":["validation","account-recovery","entity"],"backgroundTag":"schema-validation-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"}