pentaho/pentaho-kettle · error · KettleException
DatabaseJoinMeta.Exception.UnableToSaveStepInfo + id_step
Error message
DatabaseJoinMeta.Exception.UnableToSaveStepInfo + id_step
What it means
DatabaseJoinMeta.saveRep() wraps any exception thrown while persisting this step's attributes (or inserting the step-database relationship via rep.insertStepDatabase) into a KettleException whose message is 'Unable to save step info' + id_step. It exists so that repository write failures during transformation save carry the offending step id in the message.
Solutions
- Read the nested cause to find the underlying repository/SQL error
- Verify the repository user has write permission on the target partition
- Ensure the associated DatabaseMeta has been saved (non-null ObjectId) before saving the step metadata
- Reconnect/retry the repository save once the connection is healthy
Example fix
// before
rep.insertStepDatabase( id_transformation, id_step, databaseMeta.getObjectId() );
// after
if ( databaseMeta != null ) {
if ( databaseMeta.getObjectId() == null ) {
rep.save( databaseMeta, id_transformation, metaStore );
}
rep.insertStepDatabase( id_transformation, id_step, databaseMeta.getObjectId() );
} Defensive patterns
Strategy: try-catch
Validate before calling
// before saving a transformation
if ( stepMeta.getDatabaseMeta() != null && stepMeta.getDatabaseMeta().getObjectId() == null ) {
rep.save( stepMeta.getDatabaseMeta(), transMeta.getObjectId(), metaStore );
}
if ( !rep.isConnected() ) throw new KettleException( "Repository not connected" ); Try / catch
try {
transMeta.saveRep( rep, metaStore, transId );
} catch ( KettleException e ) {
if ( e.getMessage() != null && e.getMessage().contains( "Unable to save step info" ) ) {
logError( "Save failed at step " + e.getMessage() + "; cause=" + e.getCause(), e );
// reconnect and retry once
} else { throw e; }
} Prevention
- Save referenced DatabaseMetas before saving steps
- Use a repository account with write privileges
- Check repository connectivity/health before bulk saves
- Inspect getCause() to find which attribute write failed
When it happens
Trigger: Calling saveRep() (directly or when saving a transformation to a repository) when any rep.saveStepAttribute* call, rep.insertStepDatabase, or ValueMetaFactory.getNameForValueMeta throws — e.g. read-only repository, lost connection mid-save, or databaseMeta set but its ObjectId is null.
Common situations: Saving a transformation while the repository DB connection was dropped; saving into a read-only user account; a DatabaseMeta that was built in memory and never stored, so getObjectId() is null.
Related errors
- AnalyticQueryMeta.Exception.UnexpectedErrorInReadingStepInfo…
- AnalyticQueryMeta.Exception.UnableToSaveStepInfoToRepository
- DimensionLookupMeta.Exception.UnexpectedErrorReadingStepInfo…
- ERROR0003.UnableToSaveStepToRepository
- Unable to load shared objects
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/9517758b36f3359b.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/databasejoin/DatabaseJoinMeta.java:394
try {
rep.saveDatabaseMetaStepAttribute( id_transformation, id_step, "id_connection", databaseMeta );
rep.saveStepAttribute( id_transformation, id_step, "rowlimit", rowLimit );
rep.saveStepAttribute( id_transformation, id_step, "sql", sql );
rep.saveStepAttribute( id_transformation, id_step, "outer_join", outerJoin );
rep.saveStepAttribute( id_transformation, id_step, "replace_vars", replacevars );
for ( int i = 0; i < parameterField.length; i++ ) {
rep.saveStepAttribute( id_transformation, id_step, i, "parameter_field", parameterField[i] );
rep.saveStepAttribute( id_transformation, id_step, i, "parameter_type", ValueMetaFactory
.getValueMetaName( parameterType[i] ) );
}
// 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, "DatabaseJoinMeta.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 = "";
if ( databaseMeta != null ) {
Database db = new Database( loggingObject, databaseMeta );
databases = new Database[] { db }; // Keep track of this one for cancelQuery
try {
db.connect();View on GitHub (pinned to f3058517a1)