pentaho/pentaho-kettle · error · KettleException

Group field ' ' could not be found in the input stream

Error message

Group field '{0}' could not be found in the input stream

What it means

TransExecutor.initOnFirstProcessingIteration() throws this when the configured group field does not exist in the incoming row structure. The step looks up groupField via getInputRowMeta().indexOfValue() and aborts when the index is -1, since grouping cannot proceed without the column.

Solutions

  1. Open the TransExecutor dialog and re-select the group field from the actual upstream field list.
  2. Ensure the upstream step actually emits the field (check with a preview/get fields).
  3. Clear the group field setting if grouping was not intended.
  4. Match field name exactly, including case.

Example fix

// before (dialog config)
group field: "CustomerID"
// after (matches upstream row)
group field: "customer_id"
Defensive patterns

Strategy: validation

Validate before calling

// Before running, confirm group field exists in upstream row metadata
RowMetaInterface prev = transMeta.getPrevStepFields(stepName);
String groupField = transExecutorMeta.getGroupField();
if (groupField != null && !groupField.isEmpty() && prev.indexOfValue(groupField) < 0) {
  throw new IllegalStateException("Group field not in upstream rows: " + groupField);
}

Type guard

boolean groupFieldPresent(RowMetaInterface rowMeta, String field) {
  return field == null || field.isEmpty() || rowMeta.indexOfValue(field) >= 0;
}

Try / catch

try { trans.execute(new String[0]); }
catch (KettleException e) {
  if (e.getMessage().contains("Group field")) {
    log.error("Fix TransExecutor group field config: {}", e.getMessage());
  }
}

Prevention

When it happens

Trigger: First row arrives at the TransExecutor step with 'group field' set (TransExecutor.Exception.GroupFieldNotFound) but the field name is absent from the input row: renamed upstream field, wrong field name typed in the dialog, or upstream step removed the column.

Common situations: Renaming a field in the step before TransExecutor without updating the executor config; passing different row layouts (e.g. after a Select values remove); case-mismatched field names.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/transexecutor/TransExecutor.java:182

    // internal transformation's execution output
    transExecutorData.setResultRowsOutputRowMeta( new RowMeta() );
    if ( meta.getOutputRowsSourceStepMeta() != null ) {
      meta.prepareResultsRowsFields( transExecutorData.getResultRowsOutputRowMeta() );
      transExecutorData.setResultRowsRowSet( findOutputRowSet( meta.getOutputRowsSourceStepMeta().getName() ) );
    }

    // executor's self output is exactly its input
    if ( meta.getExecutorsOutputStepMeta() != null ) {
      transExecutorData.setExecutorStepOutputRowMeta( getInputRowMeta().clone() );
      transExecutorData.setExecutorStepOutputRowSet( findOutputRowSet( meta.getExecutorsOutputStepMeta().getName() ) );
    }

    // Remember which column to group on, if any...
    transExecutorData.groupFieldIndex = -1;
    if ( !Utils.isEmpty( transExecutorData.groupField ) ) {
      transExecutorData.groupFieldIndex = getInputRowMeta().indexOfValue( transExecutorData.groupField );
      if ( transExecutorData.groupFieldIndex < 0 ) {
        throw new KettleException( BaseMessages.getString(
          PKG, "TransExecutor.Exception.GroupFieldNotFound", transExecutorData.groupField ) );
      }
      transExecutorData.groupFieldMeta = getInputRowMeta().getValueMeta( transExecutorData.groupFieldIndex );
    }
  }

  private void executeTransformation( List<String> incomingFieldValues ) throws KettleException {
    TransExecutorData transExecutorData = getData();
    // If we got 0 rows on input we don't really want to execute the transformation
    if ( transExecutorData.groupBuffer.isEmpty() ) {
      return;
    }
    transExecutorData.groupTimeStart = System.currentTimeMillis();

    if ( first ) {
      discardLogLines( transExecutorData );
    }

View on GitHub (pinned to f3058517a1)