{"record":{"id":"87a67172ff88bb57","repo":"passbolt/passbolt_api","slug":"v4-related-fields-are-not-supported-for-v5-metadatatagdto","errorCode":null,"errorMessage":"V4 related fields are not supported for V5.","messagePattern":"V4 related fields are not supported for V5\\.","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltEe/Tags/src/Model/Dto/MetadataTagDto.php","lineNumber":195,"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_TAG_METADATA',\n            'slug' => $this->slug,\n            // below fields are null for now will be added in future\n            'color' => null,\n            'description' => null,\n            'icon' => null,\n        ];","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/Tags/src/Model/Dto/MetadataTagDto.php#L177-L213","documentation":"After confirming the payload is a valid V5 payload (all V5 metadata fields present), MetadataTagDto::validate() rejects any V4 field (currently 'slug') that is non-null, throwing this 400 BadRequestException. V4 and V5 representations are mutually exclusive in one request to prevent ambiguous writes.","triggerScenarios":"Sending both slug and the V5 metadata fields in the same tag create/update body, e.g. {slug: 'my-tag', metadata: ..., metadata_key_id: ..., metadata_key_type: ...}.","commonSituations":"Clients keeping the old 'slug' key in payloads for backward compatibility while adding V5 fields; generic serializers that always emit every entity property including null-able slug defaults; migrated integrations where slug is defaulted to '' rather than omitted.","solutions":["Remove 'slug' (set it to null / omit the key) when sending V5 metadata fields — the slug lives inside the encrypted metadata.","Audit serializers/DTO mappers so V4 props are stripped when a V5 payload is built.","If you need the plain-text slug, put it in the metadata's clear-text object (PASSBOLT_TAG_METADATA.slug) before encryption.","Send a pure V4 payload ({slug} only) if the Metadata plugin is not enabled."],"exampleFix":"// before: mixed payload\nPOST /tags { \"slug\": \"my-tag\", \"metadata\": \"<encrypted>\", \"metadata_key_id\": \"<uuid>\", \"metadata_key_type\": \"shared_key\" }\n// after: v5 only\nPOST /tags { \"metadata\": \"<encrypted>\", \"metadata_key_id\": \"<uuid>\", \"metadata_key_type\": \"shared_key\" }","handlingStrategy":"validation","validationCode":"if (body.metadata != null && (body.slug != null)) throw new Error('cannot mix v4 slug with v5 metadata fields');","typeGuard":"const isMixedV4V5 = (b) => b.metadata != null && b.slug != null;","tryCatchPattern":"try { await api.put(`/tags/${id}`, body); } catch (e) { if (e.response?.status === 400 && /V4 related fields/.test(e.response?.data?.message)) body = stripV4Fields(body); throw e; }","preventionTips":["Omit or null out 'slug' in all V5 tag payloads","Configure serializers to exclude V4 props once V5 is active","Put the human-readable slug inside the encrypted metadata object instead"],"tags":["http-400","validation","metadata","v4-v5-conflict"],"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"}