{"record":{"id":"cb4104474131db58","repo":"passbolt/passbolt_api","slug":"unable-to-migrate-folder-id-0-to-v5-exceptionmessage","errorCode":null,"errorMessage":"Unable to migrate folder ID: {0} to V5. {exceptionMessage}","messagePattern":"Unable to migrate folder ID: (.+?) to V5\\. (.+?)","errorType":"exception","errorClass":"InternalErrorException","httpStatus":500,"severity":"error","filePath":"plugins/PassboltCe/Metadata/src/Service/Migration/MigrateAllV4FoldersToV5Service.php","lineNumber":239,"sourceCode":"     * @return void\n     */\n    private function updateFolder(Folder $folder, array $data): void\n    {\n        try {\n            $folder = $this->Folders->patchEntity($folder, $data, [\n                'accessibleFields' => [\n                    'name' => true,\n                    'metadata' => true,\n                    'metadata_key_id' => true,\n                    'metadata_key_type' => true,\n                ],\n                'validate' => 'v5',\n            ]);\n            $this->Folders->saveOrFail($folder, ['checkRules' => false]);\n        } catch (Exception $exception) {\n            $msg = __('Unable to migrate folder ID: {0} to V5.', $folder->id);\n            $msg .= ' ' . $exception->getMessage();\n            throw new InternalErrorException($msg, 500, $exception);\n        }\n    }\n\n    /**\n     * @return \\Passbolt\\Metadata\\Model\\Entity\\MetadataKey\n     * @throws \\Cake\\Datasource\\Exception\\RecordNotFoundException When there is no metadata key record.\n     */\n    private function getMetadataKeyForEncryption(): MetadataKey\n    {\n        /** @var \\Passbolt\\Metadata\\Model\\Table\\MetadataKeysTable $metadataKeysTable */\n        $metadataKeysTable = $this->fetchTable('Passbolt/Metadata.MetadataKeys');\n\n        /** @var \\Passbolt\\Metadata\\Model\\Entity\\MetadataKey $metadataKey */\n        $metadataKey = $metadataKeysTable->getLatestActiveKey();\n\n        return $metadataKey;\n    }\n","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltCe/Metadata/src/Service/Migration/MigrateAllV4FoldersToV5Service.php#L221-L257","documentation":"Thrown by updateFolder() when patching and saving a folder with its V5 metadata fails (validation or persistence error via saveOrFail). It wraps the original exception's message into an InternalErrorException with a 500 status, and migratePersonal/migrateShared propagate it. The migration service catches it per-folder and records the error in the migration result, so the migration aborts for that folder only.","triggerScenarios":"Calling migratePersonal() or migrateShared() on a V4 folder leads to updateFolder(), where FoldersTable->patchEntity(..., ['validate' => 'v5']) produces validation errors (e.g. metadata, metadata_key_id or metadata_key_type invalid under the v5 validation ruleset), or saveOrFail() fails (database constraint/write failure).","commonSituations":"Database write failures during a bulk V4-to-V5 folder migration (disk full, lock timeout, connection dropped); the v5 validation ruleset rejecting the patched data such as a null/empty metadata field or an invalid metadata_key_id UUID; running the metadata migration command on an instance with partially applied metadata schema changes.","solutions":["Read the appended exception message in the error output; it names the exact validation field or database error that made saveOrFail() fail.","Fix the underlying database issue (disk space, connection, lock) and re-run the migration command.","Verify the folder row is consistent: metadata fields nullable constraints, metadata_key_id references an existing metadata_keys row.","Ensure the metadata plugin migrations are up to date (`ddev refresh` or run migrations) before migrating.","If a specific folder is corrupt, repair or delete/recreate it, then re-run migration."],"exampleFix":"// diagnosis: appended message says \"_metadata_key_id: The provided value is invalid\"\n// before\n$metadata_key_id => $metadataKey->id (deleted/expired key row)\n// after\n$metadataKey = $this->getMetadataKeyForEncryption(); // re-fetch latest active key and re-run migration","handlingStrategy":"try-catch","validationCode":"// before running the migration\n$foldersTable = \\Cake\\ORM\\Locator\\LocatorAwareTrait::fetchTable('Folders');\n$broken = $foldersTable->find()->where(function ($exp, $q) {\n    return $exp->isNull('metadata_key_id'); // or other preconditions\n})->count();","typeGuard":"if (!($folder instanceof \\Passbolt\\Folders\\Model\\Entity\\Folder) || $folder->id === null) { return; }","tryCatchPattern":"try {\n    (new MigrateAllV4FoldersToV5Service())->migrate();\n} catch (\\Cake\\Http\\Exception\\InternalErrorException $e) {\n    // inspect $e->getMessage() for the wrapped validation/db error, fix, re-run\n}","preventionTips":["Run plugin migrations before the V4->V5 data migration.","Check disk space and DB connectivity on the host before bulk migrations.","Run the migration on a staging copy first.","Inspect the result['errors'] array after migrate() instead of assuming all folders succeeded."],"tags":["cakephp","database-write-failed","migration","metadata","validation"],"backgroundTag":"database-write-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"}