{"record":{"id":"1d610ab8e0871ac7","repo":"passbolt/passbolt_api","slug":"v4-related-fields-are-not-supported-for-v5","errorCode":null,"errorMessage":"V4 related fields are not supported for V5.","messagePattern":"V4 related fields are not supported for V5\\.","errorType":"validation","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltCe/Metadata/src/Model/Dto/MetadataFolderDto.php","lineNumber":187,"sourceCode":"\n            throw new BadRequestException($msg);\n        }\n\n        // Now that we know that we have a valid v5 payload, we check that no v4 fields are in the payload\n        $v4SuperfluousFields = [];\n        foreach (self::V4_META_PROPS as $v4Field) {\n            if (array_key_exists($v4Field, $data) && !is_null($data[$v4Field])) {\n                $v4SuperfluousFields[] = $v4Field;\n            }\n        }\n        if (!empty($v4SuperfluousFields)) {\n            $msg = __('V4 related fields are not supported for V5.');\n            if (Configure::read('debug')) {\n                Log::error($msg);\n                Log::error(__('Superfluous fields: {0}', implode(', ', $v4SuperfluousFields)));\n            }\n\n            throw new BadRequestException($msg);\n        }\n    }\n\n    /**\n     * Returns metadata array in cleartext form as per v5 format.\n     *\n     * @return array\n     */\n    public function getClearTextMetadata(): array\n    {\n        return [\n            'object_type' => 'PASSBOLT_FOLDER_METADATA',\n            'name' => $this->name,\n            // below fields are null for now will be added in future\n            'color' => null,\n            'description' => null,\n            'icon' => null,\n        ];","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltCe/Metadata/src/Model/Dto/MetadataFolderDto.php#L169-L205","documentation":"MetadataFolderDto's validate() rejects folder creation/update payloads that mix v5 metadata fields (metadata, metadata_key_id, metadata_key_type) with v4 cleartext fields (name). Once any v5 field is present the payload is treated as v5, and any non-null v4 field triggers this BadRequestException. Passbolt throws it to enforce strict separation between the legacy v4 cleartext format and the encrypted v5 metadata format.","triggerScenarios":"POST/PUT to the folders endpoints (e.g. /folders.json or /folders/<id>.json) with body containing both `name` and any of `metadata`/`metadata_key_id`/`metadata_key_type` (all non-null), while the Metadata plugin is enabled; constructing MetadataFolderDto::fromArray with such mixed data.","commonSituations":"Migrating clients from v4 to v5 that keep sending the legacy `name` field alongside encrypted metadata; scripts or integrations built for passbolt <=4.x hitting a v5-enabled server; partially updated SDK/API wrappers that merged the two payload formats.","solutions":["Remove the v4 fields (`name` for folders) from the request payload and send only the v5 fields: metadata, metadata_key_id, metadata_key_type.","Decide the format version explicitly: for v4 send only `name` (no metadata fields), for v5 send only encrypted metadata fields.","Update the calling client/SDK to target the server's metadata (v5) format, e.g. by encrypting name into `metadata` with OpenPGP before the call.","If v5 is not intended, disable the Passbolt/Metadata plugin so the DTO nulls the v5 fields and accepts v4 payloads."],"exampleFix":"// before\nPOST /folders.json\n{\"name\": \"My folder\", \"metadata\": \"<encrypted>\", \"metadata_key_id\": \"<uuid>\", \"metadata_key_type\": \"shared_key\"}\n\n// after\nPOST /folders.json\n{\"metadata\": \"<encrypted>\", \"metadata_key_id\": \"<uuid>\", \"metadata_key_type\": \"shared_key\"}","handlingStrategy":"validation","validationCode":"// PHP (caller side)\n$v5 = ['metadata', 'metadata_key_id', 'metadata_key_type'];\n$isV5 = count(array_filter($payload, fn($v, $k) => in_array($k, $v5, true) && $v !== null, ARRAY_FILTER_USE_BOTH)) > 0;\nif ($isV5 && isset($payload['name']) && $payload['name'] !== null) {\n    unset($payload['name']); // v4 field not allowed with v5\n}","typeGuard":"function isPureV5FolderPayload(array $p): bool {\n    $hasV5 = (isset($p['metadata']) && $p['metadata'] !== null);\n    $hasV4 = (isset($p['name']) && $p['name'] !== null);\n    return $hasV5 && !$hasV4;\n}","tryCatchPattern":"try {\n    $dto = MetadataFolderDto::fromArray($payload);\n} catch (BadRequestException $e) {\n    // 400: strip v4 'name' and retry with pure v5 payload, or log and abort\n}","preventionTips":["Pick one format version per request: never mix `name` with v5 metadata fields","Encrypt the folder name into `metadata` before sending when the server has v5 enabled","Add a client-side payload lint that flags mixed v4/v5 keys before HTTP calls","Keep client SDK versions in sync with server metadata-plugin state"],"tags":["passbolt","api","v5-metadata","bad-request","payload-validation"],"backgroundTag":"conflicting-config-options","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"}