pentaho/pentaho-kettle · error · KettleException

ColumnExistsMeta.Exception.UnableToSaveStepInfo

Error message

ColumnExistsMeta.Exception.UnableToSaveStepInfo

What it means

saveRep wraps any exception while persisting the step's settings to the repository into a KettleException 'Unable to save step information... ' + id_step. The step's configuration could not be stored.

Solutions

  1. Check repository DB connectivity, credentials and disk space
  2. Retry saving after re-opening the transformation (stale ObjectId)
  3. Save locally as .ktr as a fallback, then re-import to the repository
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check repository is writable before saving
rep.connect(null);
// ensure transformation and step ObjectIds are valid
if (id_transformation == null || id_step == null) {
  throw new IllegalStateException("Stale ObjectIds: re-open the transformation before saving");
}

Try / catch

try {
  transMeta.saveRep(rep, metaStore, null, transName);
} catch (KettleException e) {
  log.error("Save failed for step " + id_step + ": " + e.getCause(), e);
  // fallback: save locally
  transMeta.saveAs(Paths.get(transName + ".ktr").toFile(), "kettle", true);
}

Prevention

When it happens

Trigger: rep.saveStepAttribute / insertStepDatabase throw during saveRep — repository connection loss, constraint violation, read-only repo, or invalid id_step/id_transformation.

Common situations: Repository database out of disk or locked; saving a transformation into a deleted folder; permission problems on the repository schema.

Related errors


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

Appendix: source

Thrown at plugins/core/impl/src/main/java/org/pentaho/di/trans/steps/columnexists/ColumnExistsMeta.java:267

  }

  public void saveRep( Repository rep, IMetaStore metaStore, ObjectId id_transformation, ObjectId id_step )
    throws KettleException {
    try {
      rep.saveDatabaseMetaStepAttribute( id_transformation, id_step, "id_connection", database );
      rep.saveStepAttribute( id_transformation, id_step, "tablename", tablename );
      rep.saveStepAttribute( id_transformation, id_step, "schemaname", schemaname );
      rep.saveStepAttribute( id_transformation, id_step, "istablenameInfield", istablenameInfield );
      rep.saveStepAttribute( id_transformation, id_step, "tablenamefield", tablenamefield );
      rep.saveStepAttribute( id_transformation, id_step, "columnnamefield", columnnamefield );
      rep.saveStepAttribute( id_transformation, id_step, "resultfieldname", resultfieldname );

      // Also, save the step-database relationship!
      if ( database != null ) {
        rep.insertStepDatabase( id_transformation, id_step, database.getObjectId() );
      }
    } catch ( Exception e ) {
      throw new KettleException(
          BaseMessages.getString( PKG, "ColumnExistsMeta.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 ( database == null ) {
      error_message = BaseMessages.getString( PKG, "ColumnExistsMeta.CheckResult.InvalidConnection" );
      cr = new CheckResult( CheckResult.TYPE_RESULT_ERROR, error_message, stepMeta );
      remarks.add( cr );
    }
    if ( Utils.isEmpty( resultfieldname ) ) {
      error_message = BaseMessages.getString( PKG, "ColumnExistsMeta.CheckResult.ResultFieldMissing" );
      cr = new CheckResult( CheckResult.TYPE_RESULT_ERROR, error_message, stepMeta );

View on GitHub (pinned to f3058517a1)