pentaho/pentaho-kettle · error · KettleException
TableExistsMeta.Exception.UnableToSaveStepInfo
Error message
TableExistsMeta.Exception.UnableToSaveStepInfo
What it means
TableExistsMeta.saveRep wraps any exception from persisting step attributes and the step-database relationship (insertStepDatabase) into the repository, appending id_step to the message. The save of this step's configuration failed.
Solutions
- Inspect the chained cause for the exact repository write error
- Ensure the step's databaseMeta is an existing, persisted connection (valid ObjectId) before saving
- Reconnect to the repository and retry saving the transformation
- Grant write privileges on R_STEP_ATTRIBUTE / R_STEP_DATABASE to the repository user
Example fix
// before: unsaved connection
meta.setDatabaseMeta(new DatabaseMeta("db", "POSTGRESQL", "Native", host, db, port, user, pass));
transMeta.saveRep(...);
// after: persist the connection first
rep.save(meta.getDatabaseMeta(), null); // assign ObjectId
transMeta.saveRep(...); Defensive patterns
Strategy: retry
Validate before calling
// pre-save checks
if (meta.getDatabaseMeta() != null && meta.getDatabaseMeta().getObjectId() == null) {
rep.save(meta.getDatabaseMeta(), null); // persist connection so insertStepDatabase has an id
} Try / catch
try { meta.saveRep(rep, metaStore, idTrans, idStep); }
catch (KettleException e) {
logError("Save failed: " + e.getCause());
rep.disconnect(); rep.connect(user, pass);
meta.saveRep(rep, metaStore, idTrans, idStep); // retry once
} Prevention
- Always persist new database connections before saving steps referencing them
- Run saves under accounts with full write access to repository tables
- Check chained causes for constraint violations and address schema issues
When it happens
Trigger: Calling saveRep when saveStepAttribute or rep.insertStepDatabase throws — connection lost mid-save, FK violation because databaseMeta has no valid ObjectId, or write-permission failure on repository tables.
Common situations: Saving a transformation whose database connection was never persisted (null ObjectId); repository DB constraint violations; read-only or quota-exceeded repository accounts.
Related errors
- CubeInputMeta.Exception.UnableToSaveStepInfo
- CubeOutputMeta.Exception.UnableToSaveStepInfo
- CubeOutputMeta.Exception.UnexpectedErrorInReadingStepInfo
- DelayMeta.Exception.UnexpectedErrorReadingStepInfo
- DelayMeta.Exception.UnexpectedErrorSavingStepInfo
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/5003d4d6792623eb.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/tableexists/TableExistsMeta.java:197
throw new KettleException( BaseMessages.getString(
PKG, "TableExistsMeta.Exception.UnexpectedErrorReadingStepInfo" ), e );
}
}
public void saveRep( Repository rep, IMetaStore metaStore, ObjectId id_transformation, ObjectId id_step ) throws KettleException {
try {
rep.saveDatabaseMetaStepAttribute( id_transformation, id_step, "id_connection", databaseMeta );
rep.saveStepAttribute( id_transformation, id_step, "tablenamefield", tablenamefield );
rep.saveStepAttribute( id_transformation, id_step, "schemaname", schemaname );
rep.saveStepAttribute( id_transformation, id_step, "resultfieldname", resultfieldname );
// Also, save the step-database relationship!
if ( databaseMeta != null ) {
rep.insertStepDatabase( id_transformation, id_step, databaseMeta.getObjectId() );
}
} catch ( Exception e ) {
throw new KettleException( BaseMessages.getString( PKG, "TableExistsMeta.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 ( databaseMeta == null ) {
error_message = BaseMessages.getString( PKG, "TableExistsMeta.CheckResult.InvalidConnection" );
cr = new CheckResult( CheckResult.TYPE_RESULT_ERROR, error_message, stepMeta );
remarks.add( cr );
}
if ( Utils.isEmpty( resultfieldname ) ) {
error_message = BaseMessages.getString( PKG, "TableExistsMeta.CheckResult.ResultFieldMissing" );
cr = new CheckResult( CheckResult.TYPE_RESULT_ERROR, error_message, stepMeta );View on GitHub (pinned to f3058517a1)