pentaho/pentaho-kettle · error · KettleException

DetectLastRowMeta.Exception.UnableToSaveStepInfo

DetectLastRowMeta.Exception.UnableToSaveStepInfo

Error message

DetectLastRowMeta.Exception.UnableToSaveStepInfo

What it means

DetectLastRowMeta.saveRep wraps any exception while saving the step's attributes to a Kettle repository into a KettleException with this localized message plus the step id. The underlying repository write failure is chained as the cause.

Solutions

  1. Inspect the chained cause for the underlying database/repository error
  2. Verify the repository is writable and has free space
  3. Re-save after reconnecting to the repository
  4. Shorten or sanitize the result field name if a database constraint is the cause

Example fix

// before
} catch ( Exception e ) {
  throw new KettleException( BaseMessages.getString( PKG, "DetectLastRowMeta.Exception.UnableToSaveStepInfo" ) + id_step, e );
}
// after: log full cause before rethrowing
} catch ( Exception e ) {
  logError( "Unable to save DetectLastRow step " + id_step, e );
  throw new KettleException( BaseMessages.getString( PKG, "DetectLastRowMeta.Exception.UnableToSaveStepInfo" ) + id_step, e );
}
Defensive patterns

Strategy: try-catch

Validate before calling

// before saving, verify repository is connected and writable
if ( repository == null || !repository.isConnected() ) {
  throw new KettleException("Repository not connected; cannot save transformation");
}

Try / catch

try {
  repository.save(transMeta, versionComment, null, metaStore);
} catch (KettleException e) {
  if (e.getMessage() != null && e.getMessage().contains("UnableToSaveStepInfo")) {
    log.error("Save failed for DetectLastRow step; cause: " + e.getCause(), e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Saving a transformation containing a DetectLastRow step when rep.saveStepAttribute throws: repository connection lost, read-only database, constraint violation, or oversized attribute value.

Common situations: Repository database read-only or out of disk space; network interruption during save; saving across incompatible Pentaho versions; invalid result field name values hitting database constraints.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/detectlastrow/DetectLastRowMeta.java:125

      throw new KettleXMLException( BaseMessages.getString(
        PKG, "DetectLastRowMeta.Exception.UnableToReadStepInfo" ), e );
    }
  }

  public void readRep( Repository rep, IMetaStore metaStore, ObjectId id_step, List<DatabaseMeta> databases ) throws KettleException {
    try {
      resultfieldname = rep.getStepAttributeString( id_step, "resultfieldname" );
    } catch ( Exception e ) {
      throw new KettleException( BaseMessages.getString(
        PKG, "DetectLastRowMeta.Exception.UnexpectedErrorReadingStepInfo" ), e );
    }
  }

  public void saveRep( Repository rep, IMetaStore metaStore, ObjectId id_transformation, ObjectId id_step ) throws KettleException {
    try {
      rep.saveStepAttribute( id_transformation, id_step, "resultfieldname", resultfieldname );
    } catch ( Exception e ) {
      throw new KettleException( BaseMessages.getString( PKG, "DetectLastRowMeta.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 ( Utils.isEmpty( resultfieldname ) ) {
      error_message = BaseMessages.getString( PKG, "DetectLastRowMeta.CheckResult.ResultFieldMissing" );
      cr = new CheckResult( CheckResult.TYPE_RESULT_ERROR, error_message, stepMeta );
      remarks.add( cr );
    } else {
      error_message = BaseMessages.getString( PKG, "DetectLastRowMeta.CheckResult.ResultFieldOK" );
      cr = new CheckResult( CheckResult.TYPE_RESULT_OK, error_message, stepMeta );
      remarks.add( cr );

View on GitHub (pinned to f3058517a1)