pentaho/pentaho-kettle · error · KettleStepException

TableOutputDialog.FailedToFindField.Message

TableOutputDialog.FailedToFindField.Message

Error message

TableOutputDialog.FailedToFindField.Message

What it means

Thrown in TableOutputHelper.processSpecifiedFieldsIfNeeded when a stream field named in the step's field mapping (info.getFieldStream()) cannot be found in the incoming row metadata (prev.searchValueMeta returns null). The Table Output step maps stream fields to database columns, and this error means the mapping references a field that no longer exists upstream. It prevents building a consistent output row for the insert.

Solutions

  1. Open the Table Output dialog and re-map the 'Stream field' column entries to fields that actually exist in the incoming stream.
  2. Verify the previous step still outputs the expected fields (View > Input fields / preview the previous step).
  3. Check for case mismatches between the mapping's stream name and the actual field name; Kettle field lookup by name is exact.
  4. If the mapping is stale after renaming, delete and recreate the field mappings (Get Fields).

Example fix

// before (mapping references missing field)
fieldStream = new String[] { "cust_name", "old_field" }; // old_field no longer produced
// after
fieldStream = new String[] { "cust_name", "customer_name" }; // matches upstream field
Defensive patterns

Strategy: validation

Validate before calling

// before running, verify every mapped stream field exists
for (String streamField : meta.getFieldStream()) {
  if (prev.searchValueMeta(streamField) == null) {
    throw new IllegalArgumentException("Mapped stream field not in input: " + streamField);
  }
}

Try / catch

// catch KettleStepException around getFields/sql
try { meta.getFields(...); }
catch (KettleStepException e) {
  if (e.getMessage().contains("FailedToFindField")) { /* re-map fields */ }
  else throw e;
}

Prevention

When it happens

Trigger: Calling processSpecifiedFieldsIfNeeded (indirectly via sql/TableOutputMeta.getFields flow) when specifyFields is enabled and info.getFieldStream()[i] does not match any field name in the previous step's RowMeta (e.g. field renamed upstream, case mismatch, or field removed).

Common situations: A transformation was edited upstream (field renamed or deleted) while the Table Output mapping still references the old name; connecting a different step with different columns; case-sensitive field name mismatch between mapping and stream.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/tableoutput/TableOutputHelper.java:146

      }
    }
    return prev;
  }

  private RowMetaInterface processSpecifiedFieldsIfNeeded( TableOutputMeta info, RowMetaInterface prev )
    throws KettleStepException {
    if ( info.specifyFields() ) {
      // Only use the fields that were specified.
      RowMetaInterface prevNew = new RowMeta();

      for ( int i = 0; i < info.getFieldDatabase().length; i++ ) {
        ValueMetaInterface insValue = prev.searchValueMeta( info.getFieldStream()[ i ] );
        if ( insValue != null ) {
          ValueMetaInterface insertValue = insValue.clone();
          insertValue.setName( info.getFieldDatabase()[ i ] );
          prevNew.addValueMeta( insertValue );
        } else {
          throw new KettleStepException( BaseMessages.getString(
            PKG, "TableOutputDialog.FailedToFindField.Message", info.getFieldStream()[ i ] ) );
        }
      }
      prev = prevNew;
    }
    return prev;
  }

  private AutoIncrementData addAutoIncrementFieldIfNeeded( TableOutputMeta info, RowMetaInterface prev ) {
    boolean autoInc = false;
    String pk = null;

    if ( info.isReturningGeneratedKeys() && !Utils.isEmpty( info.getGeneratedKeyField() ) ) {
      ValueMetaInterface valueMeta = new ValueMetaInteger( info.getGeneratedKeyField() );
      valueMeta.setLength( 15 );
      prev.addValueMeta( 0, valueMeta );
      autoInc = true;
      pk = info.getGeneratedKeyField();

View on GitHub (pinned to f3058517a1)