pentaho/pentaho-kettle · error · KettleException

GPBulkLoaderMeta.Exception.UnableToSaveStepInfoToRepository

GPBulkLoaderMeta.Exception.UnableToSaveStepInfoToRepository

Error message

GPBulkLoaderMeta.Exception.UnableToSaveStepInfoToRepository

What it means

PGBulkLoaderMeta.saveRep() wraps all repository persistence of this step's metadata (field mappings, DB connection binding via rep.insertStepDatabase) in a catch-all that rethrows as KettleException with the message "Unable to save step info to the repository" plus id_step. It means the step's serialized configuration could not be written to the Pentaho/Kettle repository. The root cause is always in the attached cause exception (repository DB down, lock, schema mismatch, etc.).

Solutions

  1. Inspect the cause (cause=true) exception for the real repository error — usually a JDBC connection or permission failure.
  2. Verify the repository connection (Tools > Repository > Connect) and that the repository database is up and writable.
  3. Retry saving the transformation after reconnecting; if persistent, re-create the step or save the transformation to a new name to get a fresh id_step.
  4. Check the repository user's write privileges on the transformation/step tables.

Example fix

// before
rep.saveStepAttribute(...) // silently throws deep inside saveRep -> wrapped
// after: verify repository is connected before saving
if ( !rep.isConnected() ) {
  rep.connect(); // ensure repository session is live
}
rep.saveStepAttribute(...);
Defensive patterns

Strategy: try-catch

Validate before calling

if ( rep == null || !rep.isConnected() ) { throw new IllegalStateException( "Repository not connected before save" ); }

Try / catch

try { stepMeta.saveRep( rep, id_transformation, id_step ); } catch ( KettleException e ) { logError( "Save failed: " + e.getCause(), e ); /* reconnect repo / retry */ }

Prevention

When it happens

Trigger: Calling saveRep(...) when the underlying repository insert/update fails — e.g. rep.insertStepDatabase(id_transformation, id_step, ...) or any earlier rep.saveStepAttribute call throws (repository connection lost, repository database read-only, duplicate/invalid id_step).

Common situations: Saving a transformation containing the PostgreSQL/GP bulk loader step while the Pentaho repository (database or file repository) is unreachable or the repository user lacks write permission; corrupted id_step after a failed transformation save; network drop between client and repository DB mid-save.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/9e2eac9e10a32775. Report an issue: GitHub.

Appendix: source

Thrown at plugins/postgresql-db-bulk-loader/impl/src/main/java/org/pentaho/di/trans/steps/pgbulkloader/PGBulkLoaderMeta.java:351

      rep.saveStepAttribute( id_transformation, id_step, "load_action", loadAction );

      rep.saveStepAttribute( id_transformation, id_step, "dbname_override", dbNameOverride );
      rep.saveStepAttribute( id_transformation, id_step, "enclosure", enclosure );
      rep.saveStepAttribute( id_transformation, id_step, "delimiter", delimiter );
      rep.saveStepAttribute( id_transformation, id_step, "stop_on_error", stopOnError );

      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, "date_mask", dateMask[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, "GPBulkLoaderMeta.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)