pentaho/pentaho-kettle · error · KettleException

MailValidatorMeta.Exception.UnableToSaveStepInfo

Error message

MailValidatorMeta.Exception.UnableToSaveStepInfo

What it means

Thrown by MailValidatorMeta.saveRep() when persisting the step's attributes to a repository fails. Saving emailSender, defaultSMTPField or isdynamicDefaultSMTP via rep.saveStepAttribute threw; the KettleException message appends the id_step. The step's configuration is not saved when this occurs.

Solutions

  1. Check the wrapped cause for the underlying JDBC error (connection, permissions, disk full)
  2. Verify the repository DB user has INSERT/UPDATE rights on R_STEP_ATTRIBUTE and that the DB is writable
  3. Reconnect to the repository and re-save the transformation
  4. Save the transformation locally as .ktr as a fallback while repository issues are fixed

Example fix

// before: saving with a dropped connection
repo.save(transMeta, null, null);
// after: reconnect and retry
try { repo.save(transMeta, null, null); }
catch (KettleException e) { repo.connect(); repo.save(transMeta, null, null); }
Defensive patterns

Strategy: try-catch

Validate before calling

// Guard before saving
if (rep == null || !rep.isConnected()) throw new IllegalStateException('Repository not connected');
if (idStep == null) throw new IllegalStateException('Step not persisted yet; id_step is null');

Type guard

boolean canSave(Repository rep, ObjectId idTrans, ObjectId idStep) {
  return rep != null && rep.isConnected() && idTrans != null && idStep != null;
}

Try / catch

try {
  meta.saveRep(rep, metaStore, idTrans, idStep);
} catch (KettleException e) {
  log.error('Save failed for step ' + idStep + ': ' + e.getCause(), e);
  // save locally as fallback
  transMeta.writeXML(new java.io.FileWriter('/tmp/backup.ktr'));
}

Prevention

When it happens

Trigger: saveRep() during 'Save' of a transformation to a repository: repository connection lost, database read-only, constraint violation, or repository exception while writing step attributes.

Common situations: Repository database down or in read-only mode; insufficient DB permissions (INSERT/UPDATE on R_STEP_ATTRIBUTE); disk full on the DB server; saving after the step id became stale.

Related errors


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

Appendix: source

Thrown at plugins/mail-validator/impl/src/main/java/org/pentaho/di/trans/steps/mailvalidator/MailValidatorMeta.java:433

  public void saveRep( Repository rep, IMetaStore metaStore, ObjectId id_transformation, ObjectId id_step ) throws KettleException {
    try {
      rep.saveStepAttribute( id_transformation, id_step, "emailfield", emailfield );
      rep.saveStepAttribute( id_transformation, id_step, "resultfieldname", resultfieldname );
      rep.saveStepAttribute( id_transformation, id_step, "ResultAsString", ResultAsString );
      rep.saveStepAttribute( id_transformation, id_step, "smtpCheck", smtpCheck );

      rep.saveStepAttribute( id_transformation, id_step, "emailValideMsg", emailValideMsg );
      rep.saveStepAttribute( id_transformation, id_step, "emailNotValideMsg", emailNotValideMsg );
      rep.saveStepAttribute( id_transformation, id_step, "errorsFieldName", errorsFieldName );
      rep.saveStepAttribute( id_transformation, id_step, "timeout", timeout );
      rep.saveStepAttribute( id_transformation, id_step, "defaultSMTP", defaultSMTP );
      rep.saveStepAttribute( id_transformation, id_step, "emailSender", emailSender );
      rep.saveStepAttribute( id_transformation, id_step, "defaultSMTPField", defaultSMTPField );

      rep.saveStepAttribute( id_transformation, id_step, "isdynamicDefaultSMTP", isdynamicDefaultSMTP );

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

    if ( Utils.isEmpty( resultfieldname ) ) {
      cr =
        new CheckResult( CheckResult.TYPE_RESULT_ERROR, BaseMessages.getString(
          PKG, "MailValidatorMeta.CheckResult.ResultFieldMissing" ), stepMeta );
    } else {
      cr =
        new CheckResult( CheckResult.TYPE_RESULT_OK, BaseMessages.getString(
          PKG, "MailValidatorMeta.CheckResult.ResultFieldOk" ), stepMeta );
    }

View on GitHub (pinned to f3058517a1)