pentaho/pentaho-kettle · error · KettleException
ProcessFilesMeta.Exception.UnableToSaveStepInfo
Error message
ProcessFilesMeta.Exception.UnableToSaveStepInfo
What it means
ProcessFilesMeta.saveRep() wraps any exception raised while persisting this step's attributes (file lists, overwrite/create-parent-folder/simulate flags) to the Kettle repository in a KettleException with this localized message plus the step ID. It means the step metadata could not be saved to the repository, not that the step itself is misconfigured.
Solutions
- Check repository database connectivity and retry the save
- Verify the repository schema is up to date (run repository upgrade/repair tools)
- Confirm the user has write permissions on the repository tables
- Inspect the wrapped cause (KettleException.getCause()) for the root SQL error
- If the repository is unstable, save the transformation as XML/file instead
Example fix
// before
transMeta.saveRep(repo, metaStore, transMeta.getObjectId(), null);
// after
if (repo != null && transMeta.getObjectId() != null) {
try {
transMeta.saveRep(repo, metaStore, transMeta.getObjectId(), null);
} catch (KettleException e) {
logError("Step info save failed: " + e.getCause());
throw e;
}
} Defensive patterns
Strategy: try-catch
Validate before calling
if (repo == null || transMeta.getObjectId() == null) throw new IllegalStateException("Repository not connected");
// also verify connectivity:
repo.connect(); Type guard
boolean canSave = repo != null && repo.isConnected() && transMeta.getObjectId() != null;
Try / catch
try {
stepMeta.getStepMetaInterface().saveRep(repo, metaStore, idTrans, idStep);
} catch (KettleException e) {
logError("Save failed for step " + idStep + ": " + e.getCause(), e);
// retry or fall back to XML export
} Prevention
- Keep repository connections healthy; reconnect before long save operations
- Run repository schema upgrades after every PDI version change
- Ensure the saving user has write permissions on repository tables
- Periodically export transformations to XML as a backup
When it happens
Trigger: Calling saveRep (e.g. via saving a transformation to a database repository) when the underlying repository insert/update of one of the step attributes fails — repository connection loss, schema mismatch, missing tables, or a null/invalid ObjectId.
Common situations: Saving a transformation over a flaky or mis-migrated repository database; repository schema missing the r_step_attribute table updates; permission problems on the repository DB; stale/closed repository connection mid-save.
Related errors
- GetTableNamesMeta.Exception.UnableToSaveStepInfo
- GPBulkLoaderMeta.Exception.UnexpectedErrorReadingStepInfoFro…
- GPBulkLoaderMeta.Exception.UnexpectedErrorReadingStepInfoFromRepository
- GPBulkLoaderMeta.Exception.UnableToSaveStepInfoToRepository
- InsertUpdateMeta.Exception.UnexpectedErrorReadingStepInfoFro…
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/fbb32bf33049525a.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/processfiles/ProcessFilesMeta.java:299
} catch ( Exception e ) {
throw new KettleException( BaseMessages.getString(
PKG, "ProcessFilesMeta.Exception.UnexpectedErrorReadingStepInfo" ), e );
}
}
@Override
public void saveRep( Repository rep, IMetaStore metaStore, ObjectId id_transformation, ObjectId id_step ) throws KettleException {
try {
rep.saveStepAttribute( id_transformation, id_step, "sourcefilenamefield", sourcefilenamefield );
rep.saveStepAttribute( id_transformation, id_step, "targetfilenamefield", targetfilenamefield );
rep.saveStepAttribute( id_transformation, id_step, "operation_type", getOperationTypeCode( operationType ) );
rep.saveStepAttribute( id_transformation, id_step, "addresultfilenames", addresultfilenames );
rep.saveStepAttribute( id_transformation, id_step, "overwritetargetfile", overwritetargetfile );
rep.saveStepAttribute( id_transformation, id_step, "createparentfolder", createparentfolder );
rep.saveStepAttribute( id_transformation, id_step, "simulate", simulate );
} catch ( Exception e ) {
throw new KettleException( BaseMessages.getString( PKG, "ProcessFilesMeta.Exception.UnableToSaveStepInfo" )
+ id_step, e );
}
}
@Override
public void check( List<CheckResultInterface> remarks, TransMeta transMeta, StepMeta stepMeta,
RowMetaInterface prev, String[] input, String[] output, RowMetaInterface info, VariableSpace space,
Repository repository, IMetaStore metaStore ) {
CheckResult cr;
String error_message = "";
// source filename
if ( Utils.isEmpty( sourcefilenamefield ) ) {
error_message = BaseMessages.getString( PKG, "ProcessFilesMeta.CheckResult.SourceFileFieldMissing" );
cr = new CheckResult( CheckResult.TYPE_RESULT_ERROR, error_message, stepMeta );
remarks.add( cr );
} else {
error_message = BaseMessages.getString( PKG, "ProcessFilesMeta.CheckResult.TargetFileFieldOK" );View on GitHub (pinned to f3058517a1)