passbolt/passbolt_api · error · BadRequestException

Few fields are missing for the V5.

Error message

Few fields are missing for the V5.

What it means

MetadataResourceDto::validateRequestPayload treats a resource payload as v5 when any of metadata, metadata_key_id, or metadata_key_type is present and non-null; it then requires ALL three v5 fields to be set. If any are missing/null it throws this BadRequestException. This enforces complete v5 encrypted-metadata payloads for resources.

Solutions

  1. Provide all three v5 fields in the payload: metadata, metadata_key_id, and metadata_key_type (all non-null).
  2. Enable debug logging (Configure::write('debug', true)) — the server logs the exact list of missing fields — and add them.
  3. If a v4 resource is intended, remove the v5 fields entirely so the payload falls back to the v4 path (name/username/uri/description).
  4. Update the client/SDK to construct complete v5 payloads, encrypting the cleartext metadata before sending.

Example fix

// before
{"metadata": "<encrypted>", "metadata_key_type": "shared_key"}

// after
{"metadata": "<encrypted>", "metadata_key_id": "<uuid>", "metadata_key_type": "shared_key"}
Defensive patterns

Strategy: validation

Validate before calling

$v5 = ['metadata', 'metadata_key_id', 'metadata_key_type'];
$present = array_filter($v5, fn($f) => isset($payload[$f]) && $payload[$f] !== null);
if (count($present) > 0 && count($present) < 3) {
    throw new InvalidArgumentException('v5 payload incomplete: missing ' . implode(', ', array_diff($v5, array_keys($present))));
}

Type guard

function isCompleteV5ResourcePayload(array $p): bool {
    return isset($p['metadata'], $p['metadata_key_id'], $p['metadata_key_type'])
        && $p['metadata'] !== null && $p['metadata_key_id'] !== null && $p['metadata_key_type'] !== null;
}

Try / catch

try {
    $dto = MetadataResourceDto::fromArray($payload);
} catch (BadRequestException $e) {
    // payload was partially v5: complete metadata_key_id/metadata_key_type or drop v5 fields
}

Prevention

When it happens

Trigger: POST/PUT to resource endpoints (/resources.json, /resources/<id>.json) with a payload including e.g. `metadata` but missing `metadata_key_id` or `metadata_key_type` (or having them null), with the Metadata plugin enabled; MetadataResourceDto::fromArray with a partial v5 payload.

Common situations: Clients migrated halfway to v5 that send the encrypted `metadata` blob but forget the key id/type; payloads where metadata_key_id is explicitly set to null for user-key scenarios; copy-pasted request examples missing one field.

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/d784f7558f80288e. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltCe/Metadata/src/Model/Dto/MetadataResourceDto.php:170

                $isV4 = false;
            } else {
                $v5MissingFields[] = $metadataField;
            }
        }
        if ($isV4) {
            return;
        }

        // Now that we know that we are in v5, we check that all the v5 metadata fields are set
        // If all v5 fields are not provided, throw an exception.
        if (!empty($v5MissingFields)) {
            $msg = __('Few fields are missing for the V5.');
            if (Configure::read('debug')) {
                Log::error($msg);
                Log::error(__('Missing fields: {0}', implode(', ', $v5MissingFields)));
            }

            throw new BadRequestException($msg);
        }

        // Now that we know that we have a valid v5 payload, we check that no v4 fields are in the payload
        $v4SuperfluousFields = [];
        foreach (self::V4_META_PROPS as $v4Field) {
            if (array_key_exists($v4Field, $payload) && !is_null($payload[$v4Field])) {
                $v4SuperfluousFields[] = $v4Field;
            }
        }
        if (!empty($v4SuperfluousFields)) {
            $msg = __('V4 related fields are not supported for V5.');
            if (Configure::read('debug')) {
                Log::error($msg);
                Log::error(__('Superfluous fields: {0}', implode(', ', $v4SuperfluousFields)));
            }

            throw new BadRequestException($msg);
        }

View on GitHub (pinned to 31c1bbc10f)