passbolt/passbolt_api · error · App\Error\Exception\CustomValidationException

Could not validate response data.

Error message

Could not validate response data.

What it means

CustomValidationException meaning the response payload failed validation because the account_recovery_request_id field is absent, empty, or not a string. The generic message hides a detailed '_required' error in the validation errors payload.

Solutions

  1. Include a valid 'account_recovery_request_id' string field in the POST body.
  2. Fix field naming/serialization so the id is sent with the expected key.
  3. Inspect the error's validation errors detail to confirm '_required' is the failing rule.

Example fix

// before
$post->post('/account-recovery/responses', ['data' => $armored]);
// after
$post->post('/account-recovery/responses', ['account_recovery_request_id' => $requestId, 'data' => $armored]);
Defensive patterns

Strategy: validation

Validate before calling

if (!isset($data['account_recovery_request_id']) || !is_string($data['account_recovery_request_id']) || $data['account_recovery_request_id'] === '') {
    throw new InvalidArgumentException('account_recovery_request_id is required.');
}

Type guard

function hasRequestId(array $d): bool { return isset($d['account_recovery_request_id']) && is_string($d['account_recovery_request_id']) && $d['account_recovery_request_id'] !== ''; }

Try / catch

try {
    $service->create($uac, $data);
} catch (\App\Error\Exception\CustomValidationException $e) {
    $errors = $e->getErrors(); // inspect account_recovery_request_id._required
}

Prevention

When it happens

Trigger: POST /account-recovery/responses without 'account_recovery_request_id' in the request body, or with null / empty string / non-string value.

Common situations: Client forgot the field; request body built dynamically and key omitted; wrong field name used (e.g. requestId); JSON body sent as form-encoded so field lost.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/4940e252b702f3c6. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltEe/AccountRecovery/src/Service/AccountRecoveryResponses/AccountRecoveryResponsesCreateService.php:142

        $service = new AccountRecoveryOrganizationPolicyGetService();
        $this->policy = $service->get();
        if ($this->policy->isDisabled()) {
            $msg = __('Recovery response cannot be created when organization policy is disabled.');
            throw new BadRequestException($msg);
        }
    }

    /**
     * @throws \App\Error\Exception\CustomValidationException if the request id is not set, not valid, not found, is not pending
     * @return \Passbolt\AccountRecovery\Model\Entity\AccountRecoveryRequest
     */
    public function assertAndGetAssociatedRequest(): AccountRecoveryRequest
    {
        $requestId = $this->getData('account_recovery_request_id');
        $msg = __('Could not validate response data.');

        if (!isset($requestId) || empty($requestId) || !is_string($requestId)) {
            throw new CustomValidationException($msg, [
                'account_recovery_request_id' => [
                    '_required' => 'The account recovery request id is required.',
                ],
            ]);
        }

        if (!Validation::uuid($requestId)) {
            throw new CustomValidationException($msg, [
                'account_recovery_request_id' => [
                    'uuid' => 'The account recovery request must be a uuid.',
                ],
            ]);
        }

        try {
            $request = $this->AccountRecoveryRequests->get($requestId);
        } catch (RecordNotFoundException $exception) {
            throw new CustomValidationException($msg, [

View on GitHub (pinned to 31c1bbc10f)