pentaho/pentaho-kettle · error · KettleException
FileExistsMeta.Exception.UnableToSaveStepInfo
Error message
FileExistsMeta.Exception.UnableToSaveStepInfo
What it means
FileExistsMeta.saveRep() writes the step attributes (filenamefield, resultfieldname, includefiletype, filetypefieldname, addresultfilenames) to the Kettle repository and wraps any failure in a KettleException with 'UnableToSaveStepInfo' plus the step id. It means the step's settings could not be persisted.
Solutions
- Check the repository database is reachable and writable; retry the save.
- Grant the repository user INSERT/UPDATE rights on the repository tables.
- Upgrade/repair the repository schema if it mismatches the current Pentaho version.
- Save the transformation to a .ktr file as a workaround while fixing the repository.
Example fix
// before // save with read-only repo user -> saveRep throws // after GRANT INSERT, UPDATE ON r_step_attribute TO kettle_user; // then retry save
Defensive patterns
Strategy: try-catch
Validate before calling
if (rep.getConnection().isReadOnly()) {
throw new IllegalStateException("Repository connection is read-only; saving will fail");
} Try / catch
try {
transMeta.saveRep(rep, metaStore, null, null);
} catch (KettleException e) {
if (e.getMessage().contains("FileExistsMeta.Exception.UnableToSaveStepInfo")) {
// check DB grants/connectivity; retry or save to file
} else { throw e; }
} Prevention
- Grant the repository user INSERT/UPDATE/DELETE on repository tables.
- Monitor DB disk space and connection health before bulk saves.
- Commit changes only after successful save; keep local ktr backups.
- Upgrade the repository schema before saving from a newer client.
When it happens
Trigger: Saving a transformation to a repository when an INSERT/UPDATE into r_step_attribute fails: DB connection lost, read-only account, constraint violation, or disk full on the DB server.
Common situations: Repository user lacking write privileges; database in read-only mode; connection dropped during save; repository schema mismatch after upgrade.
Related errors
- ElasticSearchBulkMeta.Exception.ErrorReadingRepository
- ElasticSearchBulkMeta.Exception.ErrorSavingToRepository
- ERROR_0003_Cannot_Save_Job_Entry
- ERROR_0003_Cannot_Save_Job_Entry
- ERROR_0003_Cannot_Save_Job_Entry
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/eec418610ec3e685.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/fileexists/FileExistsMeta.java:213
resultfieldname = rep.getStepAttributeString( id_step, "resultfieldname" );
includefiletype = rep.getStepAttributeBoolean( id_step, "includefiletype" );
filetypefieldname = rep.getStepAttributeString( id_step, "filetypefieldname" );
addresultfilenames = rep.getStepAttributeBoolean( id_step, "addresultfilenames" );
} catch ( Exception e ) {
throw new KettleException( BaseMessages.getString(
PKG, "FileExistsMeta.Exception.UnexpectedErrorReadingStepInfo" ), e );
}
}
public void saveRep( Repository rep, IMetaStore metaStore, ObjectId id_transformation, ObjectId id_step ) throws KettleException {
try {
rep.saveStepAttribute( id_transformation, id_step, "filenamefield", filenamefield );
rep.saveStepAttribute( id_transformation, id_step, "resultfieldname", resultfieldname );
rep.saveStepAttribute( id_transformation, id_step, "includefiletype", includefiletype );
rep.saveStepAttribute( id_transformation, id_step, "filetypefieldname", filetypefieldname );
rep.saveStepAttribute( id_transformation, id_step, "addresultfilenames", addresultfilenames );
} catch ( Exception e ) {
throw new KettleException( BaseMessages.getString( PKG, "FileExistsMeta.Exception.UnableToSaveStepInfo" )
+ id_step, e );
}
}
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 = "";
if ( Utils.isEmpty( resultfieldname ) ) {
error_message = BaseMessages.getString( PKG, "FileExistsMeta.CheckResult.ResultFieldMissing" );
cr = new CheckResult( CheckResult.TYPE_RESULT_ERROR, error_message, stepMeta );
remarks.add( cr );
} else {
error_message = BaseMessages.getString( PKG, "FileExistsMeta.CheckResult.ResultFieldOK" );
cr = new CheckResult( CheckResult.TYPE_RESULT_OK, error_message, stepMeta );
remarks.add( cr );View on GitHub (pinned to f3058517a1)