{"record":{"id":"00198b1a74d2696b","repo":"passbolt/passbolt_api","slug":"resource-metadata-key-type-is-invalid","errorCode":null,"errorMessage":"Resource metadata key type is invalid.","messagePattern":"Resource metadata key type is invalid\\.","errorType":"exception","errorClass":"Cake\\Http\\Exception\\BadRequestException","httpStatus":400,"severity":"error","filePath":"src/Controller/Share/ShareController.php","lineNumber":150,"sourceCode":"        try {\n            $resource = $this->Resources->get($resourceId);\n        } catch (RecordNotFoundException $e) {\n            throw new NotFoundException(__('The resource does not exist.'));\n        }\n        // The resource is not soft deleted.\n        if ($resource->deleted) {\n            throw new NotFoundException(__('The resource does not exist.'));\n        }\n        // The user can access the resource.\n        $acoType = PermissionsTable::RESOURCE_ACO;\n        $userId = $this->User->id();\n        if (!$this->Resources->Permissions->hasAccess($acoType, $resourceId, $userId, Permission::OWNER)) {\n            throw new ForbiddenException(__('You are not authorized to share this resource.'));\n        }\n        // V5 validations\n        $resourceDto = MetadataResourceDto::fromArray($resource->toArray());\n        if ($resourceDto->isV5() && $resource->get('metadata_key_type') === 'user_key') {\n            throw new BadRequestException(__('Resource metadata key type is invalid.'));\n        }\n    }\n\n    /**\n     * Format the result.\n     *\n     * This entry point is used by the plugin app, and due to the V1 legacy the output body must be\n     * formatted as following:\n     *\n     * [\n     *   'changes' => [\n     *     'added' => [\n     *       ['User' => ['id' => uuid]],\n     *       ...\n     *     ],\n     *     'removed' => [\n     *       ['User' => ['id' => uuid]],\n     *       ...","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Controller/Share/ShareController.php#L132-L168","documentation":"Thrown by ShareController::_assertRequestParameters during v5 (metadata) validation: the resource is v5-format and its metadata_key_type is 'user_key', which is invalid for sharing — v5 resources must be encrypted with a shared metadata key, not a per-user key.","triggerScenarios":"Sharing a v5 resource whose metadata was created with metadata_key_type='user_key' (legacy/incorrect encryption), typically data produced before metadata keys were fully rolled out or by a misconfigured client.","commonSituations":"Migrated v4→v5 data with wrong metadata_key_type; mixing client versions where one wrote user-key metadata; environments testing metadata key rotation.","solutions":["Re-encrypt the resource metadata with the proper shared metadata key (metadata key type) before sharing.","Upgrade all clients to a version that writes correct v5 metadata_key_type.","If the data is corrupt from migration, use the metadata keys maintenance/rotate tooling to fix the record."],"exampleFix":"// before (resource.metadata_key_type === 'user_key')\nawait api.put(`/share/resource/${id}`, perms);\n// after\nawait rotateMetadataKey([id]); // re-encrypt metadata with shared metadata key\nawait api.put(`/share/resource/${id}`, perms);","handlingStrategy":"validation","validationCode":"if (resource.contentType?.startsWith('v5') && resource.metadata_key_type === 'user_key') {\n  throw new Error('resource metadata must use shared metadata key, not user_key');\n}","typeGuard":"function hasValidV5Metadata(r) { return !r.metadata_key_type || r.metadata_key_type !== 'user_key'; }","tryCatchPattern":"try { await share(id, perms); } catch (e) { if (e.status === 400 && /metadata key type/.test(e.message)) { await reEncryptMetadata([id]); } else throw e; }","preventionTips":["Keep all clients on versions that write correct v5 metadata_key_type","Audit migrated v4→v5 resources for 'user_key' metadata","Rotate/re-encrypt metadata keys as part of migration validation"],"tags":["validation","v5","metadata","encryption","share"],"backgroundTag":"invalid-enum-value","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"}