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

  1. Check the KettleException cause (getCause()) for the JDBC error — connectivity, permissions, or constraint violation — and address that first.
  2. Verify repository database connectivity and retry the save once the repository is reachable.
  3. Confirm the user has write privileges (INSERT/UPDATE on r_step_attribute and related tables) in the repository.
  4. 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

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


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)