pentaho/pentaho-kettle · error · KettleException
JobMoveFiles.Error.Exception.UnableSaveRep
Error message
JobMoveFiles.Error.Exception.UnableSaveRep
What it means
This KettleException is thrown by JobEntryMoveFiles.saveRep() when persisting the move-files job entry's per-row attributes (source/destination filefolders, wildcard, etc.) to the Kettle repository fails with a KettleDatabaseException. It wraps the underlying database error and appends the job id. It signals a repository (database) problem during save, not a problem with the job entry configuration itself.
Solutions
- Check the wrapped KettleDatabaseException's cause/message for the actual JDBC error and fix the repository database or connection.
- Verify the repository R schema is up to date (run repository upgrade/repair) so all attribute columns exist.
- Test repository connectivity and credentials; reconnect and retry the save.
- If attributes are too large or violate constraints, shorten/normalize field values (paths, wildcards) and resave.
Example fix
// before
rep.saveJobEntryAttribute( id_job, getObjectId(), i, "wildcard", wildcard[i] );
// after
// ensure rep is connected first
if ( !rep.isConnected() && !rep.connect() ) { throw new KettleException( "Repository not connected" ); }
rep.saveJobEntryAttribute( id_job, getObjectId(), i, "wildcard", wildcard[i] ); Defensive patterns
Strategy: try-catch
Validate before calling
// before save
if ( !rep.isConnected() ) { rep.connect(); }
if ( wildcard == null || destination_filefolder == null ) { throw new KettleValidationException( "entry fields not initialized" ); } Type guard
boolean canSave = (rep != null && rep.isConnected());
Try / catch
try { jobEntry.saveRep( rep, metaStore, id_job ); } catch ( KettleException e ) { logError( "Repository save failed: " + e.getCause(), e ); /* retry after reconnect */ } Prevention
- Ensure the repository is connected and healthy before programmatic saves
- Keep the repository schema upgraded to your Pentaho version
- Validate entry fields are initialized before save
- Catch KettleException and log the cause chain, not just the message
When it happens
Trigger: Calling saveRep() on a JobEntryMoveFiles when the repository database insert/update of job entry attributes fails — e.g. repository connection lost, table locked, constraint violation, or oversized attribute values.
Common situations: Saving a job with a 'Move files' entry while the repository database is down or the network to it dropped; repository schema version mismatch (missing columns); write permissions revoked for the repository user.
Related errors
- Unable to save job entry of type 'Msgbox Info' to the…
- ERROR_0002
- HTTPMeta.Exception.UnableToSaveStepInfo
- JobDosToUnix.Error.Exception.UnableLoadRep
- JobDosToUnix.Error.Exception.UnableSaveRep
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/b70ddf056beae520.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/job/entries/movefiles/JobEntryMoveFiles.java:358
rep.saveJobEntryAttribute( id_job, getObjectId(), "create_move_to_folder", create_move_to_folder );
rep
.saveJobEntryAttribute(
id_job, getObjectId(), "AddMovedDateBeforeExtension", AddMovedDateBeforeExtension );
rep.saveJobEntryAttribute( id_job, getObjectId(), "simulate", simulate );
// save the arguments...
if ( source_filefolder != null ) {
for ( int i = 0; i < source_filefolder.length; i++ ) {
rep.saveJobEntryAttribute( id_job, getObjectId(), i, "source_filefolder", source_filefolder[i] );
rep
.saveJobEntryAttribute(
id_job, getObjectId(), i, "destination_filefolder", destination_filefolder[i] );
rep.saveJobEntryAttribute( id_job, getObjectId(), i, "wildcard", wildcard[i] );
}
}
} catch ( KettleDatabaseException dbe ) {
throw new KettleException( BaseMessages.getString( PKG, "JobMoveFiles.Error.Exception.UnableSaveRep" )
+ id_job, dbe );
}
}
public Result execute( Result previousResult, int nr ) throws KettleException {
Result result = previousResult;
List<RowMetaAndData> rows = result.getRows();
RowMetaAndData resultRow = null;
result.setNrErrors( 1 );
result.setResult( false );
NrErrors = 0;
NrSuccess = 0;
successConditionBroken = false;
successConditionBrokenExit = false;
limitFiles = Const.toInt( environmentSubstitute( getNrErrorsLessThan() ), 10 );
if ( log.isDetailed() ) {View on GitHub (pinned to f3058517a1)