passbolt/passbolt_api · error · InternalErrorException
No permission found for folder ID
Error message
No permission found for folder ID {0} What it means
The V4-to-V5 folder migration requires every folder to have at least one permission (a personal folder needs its owner's permission to know whose key encrypts the metadata). If the loaded folder's permissions collection is empty, an InternalErrorException naming the folder ID is thrown from migrate().
Solutions
- Delete or repair the orphaned folder(s) — restore permissions for the folder identified in the message.
- Re-grant an owner permission to the folder, then re-run the migration.
- Skip folders with no permissions (log their IDs) so the batch can continue and address them manually.
- Audit with SQL: folders left-joined to permissions where permissions.id IS NULL.
Example fix
// before: any folder is processed
$folders = $foldersTable->find()->contain('Permissions')->all();
// after: require at least one permission
$folders = $foldersTable->find()
->innerJoinWith('Permissions')
->distinct()
->contain('Permissions')->all(); Defensive patterns
Strategy: validation
Validate before calling
$orphanFolders = TableRegistry::getTableLocator()->get('Folders')
->find()
->notMatching('Permissions')
->all(); // repair or delete these before migrating Type guard
if (count($folder->permissions) === 0) { continue; } // skip and log Try / catch
try {
$service->migrate($uac);
} catch (\Cake\Http\Exception\InternalErrorException $e) {
if (str_starts_with($e->getMessage(), 'No permission found for folder')) {
// repair the folder identified in the message
}
} Prevention
- Never delete permissions without deleting or reassigning the folder
- Run data-integrity checks (folders without permissions) before migrations
- Validate backups/restores leave permissions consistent with folders
When it happens
Trigger: Migrating a folder that exists in the folders table but has zero rows in permissions — orphaned folder data from cascading permission deletions, manual DB edits, or restore inconsistencies.
Common situations: Databases where permissions were removed without deleting the folder; partially restored backups; folders inherited visibility through ACL cleanup gone wrong.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Could not validate move data.
- Folder creation with cleartext metadata not allowed.
- Folder ID " " is already V5
- No permission found for resource ID
- No user found for the personal tag id
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/41e856830c922d4c.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltCe/Metadata/src/Service/Migration/MigrateAllV4FoldersToV5Service.php:104
->toArray();
if (empty($folders)) {
$this->addError(['error_message' => __('No folders to migrate.')]);
return $this->getResult();
}
foreach ($folders as $folder) {
$dto = MetadataFolderDto::fromArray($folder->toArray());
try {
if ($dto->isV5()) {
$msg = __('Folder ID "{0}" is already V5', $folder->id);
throw new InternalErrorException($msg);
}
if (count($folder->permissions) === 0) {
$msg = __('No permission found for folder ID {0}', $folder->id);
throw new InternalErrorException($msg);
}
if (count($folder->permissions) === 1) {
$this->migratePersonal($dto, $folder);
} else {
$this->migrateShared($dto, $folder);
}
$this->addMigrated($folder);
} catch (Exception $e) {
// Continue with next resource if any error
$error = ['folder_id' => $folder->id, 'error_message' => $e->getMessage()];
if (Configure::read('debug')) {
$error['trace'] = $e->getTraceAsString();
}
$this->addError($error);
}
}
View on GitHub (pinned to 31c1bbc10f)