pentaho/pentaho-kettle · error · KettleException
Unable to delete directory with path [
Error message
Unable to delete directory with path [
What it means
Catch-all wrapper in deleteRepositoryDirectory: any exception from the guards above or from pur.deleteFile is wrapped as "Unable to delete directory with path [...]" with the root cause chained; the write lock is released in finally.
Solutions
- Inspect e.getCause() — if it is RepositoryObjectAccessException USER_HOME_DIR, honor it and skip the folder.
- Verify the user has delete permission on the folder (PUC security settings).
- Re-fetch the directory to refresh its ObjectId before retrying the delete.
- Delete children individually if a server-side constraint blocks the recursive delete.
Example fix
// before
repo.deleteRepositoryDirectory(dir, true);
// after
try { repo.deleteRepositoryDirectory(repo.findDirectory(dir.getPath()), true); } catch (KettleException e) { logger.warn("delete {} failed: {}", dir.getPath(), e.getCause()); } Defensive patterns
Strategy: try-catch
Validate before calling
if (repo.findDirectory(dir.getPath()) == null) return; // already gone
Try / catch
try { repo.deleteRepositoryDirectory(dir, true); } catch (KettleException e) { Throwable c = e.getCause(); if (c instanceof RepositoryObjectAccessException) handleAccess((RepositoryObjectAccessException) c); else retryWithFreshObjectId(dir); } Prevention
- Re-fetch the directory to refresh ObjectId before deleting
- Check delete ACLs beforehand
- In recursive deletions, catch per-folder and continue
When it happens
Trigger: pur.deleteFile fails — the caller lacks delete permission, the folder contains undeletable content, the ObjectId is stale after concurrent modification, or a JCR/server error occurs; also wraps RepositoryObjectAccessException from the home-folder guards into a KettleException.
Common situations: Deleting folders under /public without delete ACLs; another client moved/deleted the folder first; recursive deletions partially failing mid-tree.
Related errors
- PurRepository.FailedDirectoryCreation.Message
- PurRepository.invalidRepositoryDirectory
- Unable to create directory with path [
- Unable to get list of object names from directory [
- Unable to save repository directory with path [
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/8d599966ab165f66.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/pur/core/src/main/java/org/pentaho/di/repository/pur/PurRepository.java:583
folder = pur.getFileById( dir.getObjectId().getId() );
// Fetch the user's home directory
homeFolder = pur.getFile( ClientRepositoryPaths.getUserHomeFolderPath( user.getLogin() ) );
// Make sure the user is not trying to delete their own home directory
if ( isSameOrAncestorFolder( folder, homeFolder ) ) {
// Then throw an exception that the user cannot delete their own home directory
throw new KettleException( "You are not allowed to delete your home folder." );
}
if ( !deleteHomeDirectories && isUserHomeDirectory( folder ) ) {
throw new RepositoryObjectAccessException( "Cannot delete another users home directory",
RepositoryObjectAccessException.AccessExceptionType.USER_HOME_DIR );
}
pur.deleteFile( dir.getObjectId().getId(), null );
rootRef.clearRef();
} catch ( Exception e ) {
throw new KettleException( "Unable to delete directory with path [" + getPath( null, dir, null ) + "]", e );
} finally {
readWriteLock.writeLock().unlock();
}
}
@Override
public ObjectId renameRepositoryDirectory( final ObjectId dirId, final RepositoryDirectoryInterface newParent,
final String newName ) throws KettleException {
return renameRepositoryDirectory( dirId, newParent, newName, false );
}
@Override
public ObjectId renameRepositoryDirectory( final ObjectId dirId, final RepositoryDirectoryInterface newParent,
final String newName, final boolean renameHomeDirectories )
throws KettleException {
// dir ID is used to find orig obj; new parent is used as new parent (might be null meaning no change in parent);
// new name is used as new file name (might be null meaning no change in name)
String finalName = null;View on GitHub (pinned to f3058517a1)