pentaho/pentaho-kettle · error · KettleException

ProcessFilesMeta.Exception.UnableToSaveStepInfo

Error message

ProcessFilesMeta.Exception.UnableToSaveStepInfo

What it means

ProcessFilesMeta.saveRep() wraps any exception raised while persisting this step's attributes (file lists, overwrite/create-parent-folder/simulate flags) to the Kettle repository in a KettleException with this localized message plus the step ID. It means the step metadata could not be saved to the repository, not that the step itself is misconfigured.

Solutions

  1. Check repository database connectivity and retry the save
  2. Verify the repository schema is up to date (run repository upgrade/repair tools)
  3. Confirm the user has write permissions on the repository tables
  4. Inspect the wrapped cause (KettleException.getCause()) for the root SQL error
  5. If the repository is unstable, save the transformation as XML/file instead

Example fix

// before
transMeta.saveRep(repo, metaStore, transMeta.getObjectId(), null);
// after
if (repo != null && transMeta.getObjectId() != null) {
  try {
    transMeta.saveRep(repo, metaStore, transMeta.getObjectId(), null);
  } catch (KettleException e) {
    logError("Step info save failed: " + e.getCause());
    throw e;
  }
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (repo == null || transMeta.getObjectId() == null) throw new IllegalStateException("Repository not connected");
// also verify connectivity:
repo.connect();

Type guard

boolean canSave = repo != null && repo.isConnected() && transMeta.getObjectId() != null;

Try / catch

try {
  stepMeta.getStepMetaInterface().saveRep(repo, metaStore, idTrans, idStep);
} catch (KettleException e) {
  logError("Save failed for step " + idStep + ": " + e.getCause(), e);
  // retry or fall back to XML export
}

Prevention

When it happens

Trigger: Calling saveRep (e.g. via saving a transformation to a database repository) when the underlying repository insert/update of one of the step attributes fails — repository connection loss, schema mismatch, missing tables, or a null/invalid ObjectId.

Common situations: Saving a transformation over a flaky or mis-migrated repository database; repository schema missing the r_step_attribute table updates; permission problems on the repository DB; stale/closed repository connection mid-save.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/processfiles/ProcessFilesMeta.java:299

    } catch ( Exception e ) {
      throw new KettleException( BaseMessages.getString(
        PKG, "ProcessFilesMeta.Exception.UnexpectedErrorReadingStepInfo" ), e );
    }
  }

  @Override
  public void saveRep( Repository rep, IMetaStore metaStore, ObjectId id_transformation, ObjectId id_step ) throws KettleException {
    try {
      rep.saveStepAttribute( id_transformation, id_step, "sourcefilenamefield", sourcefilenamefield );
      rep.saveStepAttribute( id_transformation, id_step, "targetfilenamefield", targetfilenamefield );
      rep.saveStepAttribute( id_transformation, id_step, "operation_type", getOperationTypeCode( operationType ) );
      rep.saveStepAttribute( id_transformation, id_step, "addresultfilenames", addresultfilenames );
      rep.saveStepAttribute( id_transformation, id_step, "overwritetargetfile", overwritetargetfile );
      rep.saveStepAttribute( id_transformation, id_step, "createparentfolder", createparentfolder );
      rep.saveStepAttribute( id_transformation, id_step, "simulate", simulate );

    } catch ( Exception e ) {
      throw new KettleException( BaseMessages.getString( PKG, "ProcessFilesMeta.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 = "";

    // source filename
    if ( Utils.isEmpty( sourcefilenamefield ) ) {
      error_message = BaseMessages.getString( PKG, "ProcessFilesMeta.CheckResult.SourceFileFieldMissing" );
      cr = new CheckResult( CheckResult.TYPE_RESULT_ERROR, error_message, stepMeta );
      remarks.add( cr );
    } else {
      error_message = BaseMessages.getString( PKG, "ProcessFilesMeta.CheckResult.TargetFileFieldOK" );

View on GitHub (pinned to f3058517a1)