pentaho/pentaho-kettle · error · KettleException
File is currently locked by another user for editing
Error message
File is currently locked by another user for editing
What it means
In collaborative Pentaho repositories, files can be locked by a user for editing. When saving with checkLock enabled, if the target file is locked and the current user lacks permission to unlock it (i.e. it's someone else's lock), the save is refused with this KettleException to prevent clobbering another user's work.
Solutions
- Ask the lock owner to save and release the lock, then retry
- Unlock the file via the repository browser (Lock > Unlock) or unifiedRepositoryLockService.unlockFileById(id) if you have permission
- Admin: force-unlock the file in Pentaho User Console / repository admin
- Save to a new name/path with 'Save As' if the lock cannot be released
Defensive patterns
Strategy: try-catch
Validate before calling
RepositoryFile f = pur.getFileById(id.getId());
boolean blocked = f.isLocked() && !unifiedRepositoryLockService.canUnlockFileById(id);
if (blocked) throw new KettleException("File " + f.getName() + " is locked by another user"); Try / catch
try {
repository.save(element, comment, null, true);
} catch (KettleException e) {
if (e.getMessage() != null && e.getMessage().contains("locked by another user")) {
// surface lock-owner info to the user; offer Save As or unlock request
} else throw e;
} Prevention
- Check lock status via the repository browser before editing shared files
- Acquire a lock yourself before long edits
- Coordinate team access to shared transformations; admin-force-unlock stale locks
When it happens
Trigger: Calling PurRepository.save/saveRepositoryObject on an existing file whose UnifiedRepository file.isLocked() is true while unifiedRepositoryLockService.canUnlockFileById(id) is false.
Common situations: Two developers editing the same transformation in Spoon; a stale lock left by a crashed session or departed user; saving under an account with no lock-admin rights over a locked file.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- AbsSecurityProvider.ERROR_0002_UNABLE_TO_ACCESS_IS_ALLOWED
- AddSequenceMeta.Exception.UnableToReadStepInfo
- AddSequenceMeta.Exception.UnableToSaveStepInfo
- Error loading job details
- File is in the Trash. Use Save As.
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/92648bb6c2ae68f4.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/pur/core/src/main/java/org/pentaho/di/repository/pur/PurRepository.java:3457
if ( Import.ROOT_DIRECTORY.equals( element.getRepositoryDirectory().toString() ) ) {
// We don't have possibility to read this file via UI
throw new KettleException( BaseMessages.getString( PKG, "PurRepository.fileCannotBeSavedInRootDirectory",
element.getName() + element.getRepositoryElementType().getExtension() ) );
}
ExtensionPointHandler.callExtensionPoint( log, KettleExtensionPoint.BeforeSaveToRepository.id, element );
final boolean isUpdate = ( element.getObjectId() != null && element.getObjectId().getId() != null );
RepositoryFile file = null;
if ( isUpdate ) {
readWriteLock.readLock().lock();
try {
ObjectId id = element.getObjectId();
file = pur.getFileById( id.getId() );
if ( checkLock && file.isLocked() && !unifiedRepositoryLockService.canUnlockFileById( id ) ) {
throw new KettleException( "File is currently locked by another user for editing" );
}
if ( checkDeleted && isInTrash( file ) ) {
// absolutely awful to have UI references in this class :(
throw new KettleException( "File is in the Trash. Use Save As." );
}
} finally {
readWriteLock.readLock().unlock();
}
readWriteLock.writeLock().lock();
try {
// update title and description
file =
new RepositoryFile.Builder( file ).title( RepositoryFile.DEFAULT_LOCALE, element.getName() ).createdDate(
versionDate != null ? versionDate.getTime() : new Date() ).description( RepositoryFile.DEFAULT_LOCALE,
Const.NVL( element.getDescription(), "" ) ).build();
file =View on GitHub (pinned to f3058517a1)