pentaho/pentaho-kettle · error · KettleException
MySQLBulkLoaderMeta.Exception.UnableToSaveStepInfoToRepository
MySQLBulkLoaderMeta.Exception.UnableToSaveStepInfoToRepository
Error message
MySQLBulkLoaderMeta.Exception.UnableToSaveStepInfoToRepository
What it means
saveRep persists the step's settings to a repository and wraps any failure in a KettleException with UnableToSaveStepInfoToRepository (with id_step appended to the message). It means writing the MySQL Bulk Loader's attributes — field mappings, the step-database relation via insertStepDatabase, etc. — to the repository failed. The underlying cause is attached.
Solutions
- Check the KettleException cause (getCause()) for the JDBC error — connectivity, permissions, or constraint violation — and address that first.
- Verify repository database connectivity and retry the save once the repository is reachable.
- Confirm the user has write privileges (INSERT/UPDATE on r_step_attribute and related tables) in the repository.
- If a partial save left orphaned rows, clean them up and save again.
Example fix
// before: saving with a read-only repository user repoUser = "reader"; // after: use a user with write privileges on the repository schema repoUser = "pdi_admin"; repository.connect( repoUser, repoPassword ); transformation.saveRep( repository );
Defensive patterns
Strategy: try-catch
Validate before calling
// Before saving, verify repository connectivity
if ( !repository.isConnected() ) {
throw new IllegalStateException( "Repository not connected; cannot save transformation." );
} Try / catch
try {
transMeta.saveRep( repository, null, null );
} catch ( KettleException e ) {
if ( String.valueOf( e.getMessage() ).contains( "UnableToSaveStepInfo" ) ) {
log.error( "Repository save failed for step; cause:", e.getCause() );
// fallback: persist to a local .ktr so work is not lost
transMeta.saveXML( backupKtrPath );
} else {
throw e;
}
} Prevention
- Confirm the repository user has INSERT/UPDATE privileges before saving.
- Save a local .ktr copy alongside repository saves as a fallback.
- Monitor repository DB health (disk space, connections) before metadata operations.
- Retry the save on transient connectivity errors.
When it happens
Trigger: saveRep (called when saving a transformation to a repository) throws when rep.saveStepAttribute or rep.insertStepDatabase fail — repository connection loss, insufficient privileges, a constraint violation, or any other exception while writing step attributes.
Common situations: Repository database down or network dropped mid-save; user lacks INSERT/UPDATE privileges on repository tables; duplicate key from a partially completed previous save; repository storage full or read-only.
Related errors
- AddSequenceMeta.Exception.UnableToSaveStepInfo
- DeleteMeta.Exception.UnableToSaveStepInfo
- ERROR_0003
- InsertUpdateMeta.Exception.UnableToSaveStepInfoToRepository
- JobEntryMSAccessBulkLoad.Meta.UnableSave
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/bc76a77a344d9f99.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/mysql-bulk-loader/impl/src/main/java/org/pentaho/di/trans/steps/mysqlbulkloader/MySQLBulkLoaderMeta.java:389
rep.saveStepAttribute( id_transformation, id_step, "fifo_file_name", fifoFileName );
rep.saveStepAttribute( id_transformation, id_step, "replace", replacingData );
rep.saveStepAttribute( id_transformation, id_step, "ignore", ignoringErrors );
rep.saveStepAttribute( id_transformation, id_step, "local", localFile );
rep.saveStepAttribute( id_transformation, id_step, "bulk_size", bulkSize );
for ( int i = 0; i < fieldTable.length; i++ ) {
rep.saveStepAttribute( id_transformation, id_step, i, "stream_name", fieldTable[i] );
rep.saveStepAttribute( id_transformation, id_step, i, "field_name", fieldStream[i] );
rep.saveStepAttribute( id_transformation, id_step, i, "field_format_ok",
getFieldFormatTypeCode( fieldFormatType[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,
"MySQLBulkLoaderMeta.Exception.UnableToSaveStepInfoToRepository" )
+ id_step, e );
}
}
@Override
public void getFields( Bowl bowl, RowMetaInterface rowMeta, String origin, RowMetaInterface[] info, StepMeta nextStep,
VariableSpace space, Repository repository, IMetaStore metaStore ) throws KettleStepException {
// Default: nothing changes to rowMeta
}
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 ) {View on GitHub (pinned to f3058517a1)