pentaho/pentaho-kettle · error · KettleException
File is in the Trash. Use Save As.
Error message
File is in the Trash. Use Save As.
What it means
Before saving, PurRepository checks (when checkDeleted is enabled) whether the target file currently lives in the repository Trash. A deleted file cannot be updated in place, so the save is aborted and the developer is told to use Save As. The message deliberately references UI behavior.
Solutions
- Use 'Save As' to save the element to a new file/path
- Restore the file from the repository Trash, then retry the save
- Re-create the file at the original location and then save over it
Defensive patterns
Strategy: validation
Validate before calling
RepositoryFile f = pur.getFileById(element.getObjectId().getId());
if (f == null || (f.isDeleted() != null && f.isDeleted())) {
throw new KettleException("File no longer exists (in trash). Use Save As.");
} Try / catch
try {
repository.save(element, comment, null, true);
} catch (KettleException e) {
if (e.getMessage() != null && e.getMessage().contains("Trash")) {
// prompt user for Save As with a new name/path
} else throw e;
} Prevention
- Re-fetch the file by ID before saving a long-lived reference
- Avoid keeping stale ObjectIds across long editing sessions
- If the file was deleted, restore from trash or save under a new name
When it happens
Trigger: Calling PurRepository.save on a file whose ObjectId resolves to a file in the trash (isInTrash(file) is true) — e.g. saving a transformation that was deleted in the repository browser before the save.
Common situations: Long-running Spoon session where a colleague deleted the transformation mid-edit; saving after accidentally deleting the file; scripts holding stale ObjectIds to deleted files.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- AbsSecurityProvider.ERROR_0002_UNABLE_TO_ACCESS_IS_ALLOWED
- AddSequenceMeta.Exception.UnableToReadStepInfo
- AddSequenceMeta.Exception.UnableToSaveStepInfo
- Error loading job details
- File is currently locked by another user for editing
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/eb5989f3fa706b21.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/pur/core/src/main/java/org/pentaho/di/repository/pur/PurRepository.java:3461
}
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 =
pur.updateFile( file, new NodeRepositoryFileData( objectTransformer.elementToDataNode( element ) ),
versionComment );
} catch ( SOAPFaultException e ) {
if ( e.getMessage().contains( UnifiedRepositoryUpdateFileException.PREFIX ) ) {View on GitHub (pinned to f3058517a1)