{"record":{"id":"661cd56f6d8a3ee6","repo":"passbolt/passbolt_api","slug":"few-fields-are-missing-for-the-v5-metadatatagdto","errorCode":null,"errorMessage":"Few fields are missing for the V5.","messagePattern":"Few fields are missing for the V5\\.","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltEe/Tags/src/Model/Dto/MetadataTagDto.php","lineNumber":178,"sourceCode":"                $isV4 = false;\n            } else {\n                $v5MissingFields[] = $metadataField;\n            }\n        }\n        if ($isV4) {\n            return;\n        }\n\n        // Now that we know that we are in v5, we check that all the v5 metadata fields are set\n        // If all v5 fields are not provided, throw an exception.\n        if (!empty($v5MissingFields)) {\n            $msg = __('Few fields are missing for the V5.');\n            if (Configure::read('debug')) {\n                Log::error($msg);\n                Log::error(__('Missing fields: {0}', implode(', ', $v5MissingFields)));\n            }\n\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        }","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/Tags/src/Model/Dto/MetadataTagDto.php#L160-L196","documentation":"MetadataTagDto::validate() classifies a payload as V5 if any of metadata, metadata_key_id, metadata_key_type is set; in that case ALL three must be non-null, otherwise it throws this 400 BadRequestException from the constructor (so fromArray() on request data throws too). With debug enabled it logs the exact missing field names.","triggerScenarios":"Creating/updating a tag with a partial V5 payload, e.g. {metadata, metadata_key_type} without metadata_key_id, or sending metadata_key_id alone; clients half-migrated from V4 that start mixing encryption fields.","commonSituations":"API consumers migrating integrations to the V5 metadata format incrementally; copy-pasting example payloads and omitting one field; serialization layers dropping null/empty fields so only some V5 keys arrive; feature plugin (Metadata) enabled but client library still building V5 payloads manually.","solutions":["Send all three V5 fields together: metadata (encrypted JSON string), metadata_key_id (UUID), metadata_key_type ('shared_key' or 'user_key').","Or send a pure V4 payload ({slug}) with none of the V5 fields at all.","Use the passbolt JS/CLI SDK's metadata encryption helpers to build the complete V5 payload.","Enable debug mode to read the 'Missing fields:' log line identifying exactly which keys are absent."],"exampleFix":"// before: partial v5 payload\nPOST /tags { \"metadata\": \"<encrypted>\", \"metadata_key_type\": \"shared_key\" }\n// after: complete v5 payload\nPOST /tags {\n  \"metadata\": \"<encrypted>\",\n  \"metadata_key_id\": \"<uuid>\",\n  \"metadata_key_type\": \"shared_key\"\n}","handlingStrategy":"validation","validationCode":"const v5 = ['metadata', 'metadata_key_id', 'metadata_key_type'].filter(k => body[k] != null);\nif (v5.length > 0 && v5.length < 3) throw new Error(`incomplete v5 payload, missing: ${['metadata','metadata_key_id','metadata_key_type'].filter(k => body[k] == null)}`);","typeGuard":"const isCompleteV5Tag = (b) => ['metadata','metadata_key_id','metadata_key_type'].every(k => b[k] != null);","tryCatchPattern":"try { await api.post('/tags', body); } catch (e) { if (e.response?.status === 400 && /Few fields are missing/.test(e.response?.data?.message)) console.error('send all three v5 fields or none'); throw e; }","preventionTips":["Always send V5 fields as an all-or-nothing set","Build payloads with the SDK's metadata encryption helpers","Enable server debug mode to log which fields are missing","Strip serializers that drop falsy/null keys from V5 payloads"],"tags":["http-400","validation","metadata","v5-migration"],"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"}