pentaho/pentaho-kettle · error · KettleException

StringCutMeta.Exception.UnableToSaveStepInfo

Error message

StringCutMeta.Exception.UnableToSaveStepInfo

What it means

StringCutMeta throws this KettleException in saveRep() when writing the step's settings to the Pentaho repository fails unexpectedly, with the step ObjectId appended to the message. The underlying repository error is in the cause chain.

Solutions

  1. Check the wrapped cause for the true write error
  2. Reconnect to the repository and retry saving
  3. Verify id_transformation/id_step are valid and the transformation still exists
  4. Save to file (XML) as a fallback and re-import later

Example fix

// before
throw new KettleException(BaseMessages.getString(PKG, "StringCutMeta.Exception.UnableToSaveStepInfo") + id_step, e);
// after
// ensure the repository session is alive before saving:
if (!repository.isConnected()) repository.connect(user, pass); // retry saveRep
Defensive patterns

Strategy: try-catch

Validate before calling

// before saveRep
if (!repository.isConnected()) repository.connect(user, pass);
if (idTransformation == null || idStep == null) throw new IllegalArgumentException("ids required");
if (meta.getFieldInStream() == null) meta.setDefault(); // avoid NPE inside save

Try / catch

try {
  meta.saveRep(repository, metaStore, idTransformation, idStep);
} catch (KettleException e) {
  logError("Repository save failed for " + idStep + ": " + e.getCause(), e);
  // fallback: persist to file
  // Files.write(path, meta.getXML().getBytes(StandardCharsets.UTF_8));
}

Prevention

When it happens

Trigger: Calling saveRep() when any rep.saveStepAttribute(...) for in_stream_name/out_stream_name/cut_from/cut_to throws — write failure, closed connection, invalid object ids, or null field arrays.

Common situations: Repository outage or read-only mode during save; transformation record deleted concurrently; repository column length exceeded by field names.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/stringcut/StringCutMeta.java:221

        cutTo[i] = Const.NVL( rep.getStepAttributeString( id_step, i, "cut_to" ), "" );
      }
    } catch ( Exception e ) {
      throw new KettleException( BaseMessages.getString(
        PKG, "StringCutMeta.Exception.UnexpectedErrorInReadingStepInfo" ), e );
    }
  }

  public void saveRep( Repository rep, IMetaStore metaStore, ObjectId id_transformation, ObjectId id_step ) throws KettleException {
    try {

      for ( int i = 0; i < fieldInStream.length; i++ ) {
        rep.saveStepAttribute( id_transformation, id_step, i, "in_stream_name", fieldInStream[i] );
        rep.saveStepAttribute( id_transformation, id_step, i, "out_stream_name", fieldOutStream[i] );
        rep.saveStepAttribute( id_transformation, id_step, i, "cut_from", cutFrom[i] );
        rep.saveStepAttribute( id_transformation, id_step, i, "cut_to", cutTo[i] );
      }
    } catch ( Exception e ) {
      throw new KettleException( BaseMessages.getString( PKG, "StringCutMeta.Exception.UnableToSaveStepInfo" )
        + id_step, e );
    }
  }

  @Override
  public void getFields( Bowl bowl, RowMetaInterface inputRowMeta, String name, RowMetaInterface[] info, StepMeta nextStep,
    VariableSpace space, Repository repository, IMetaStore metaStore ) throws KettleStepException {
    for ( int i = 0; i < fieldOutStream.length; i++ ) {
      ValueMetaInterface v;
      if ( !Utils.isEmpty( fieldOutStream[i] ) ) {
        v = new ValueMetaString( space.environmentSubstitute( fieldOutStream[i] ) );
        v.setLength( 100, -1 );
        v.setOrigin( name );
        inputRowMeta.addValueMeta( v );
      } else {
        v = inputRowMeta.searchValueMeta( fieldInStream[i] );
        if ( v == null ) {
          continue;

View on GitHub (pinned to f3058517a1)