pentaho/pentaho-kettle · error · KettleException

Could not find field in stream

Error message

Could not find field  in stream

What it means

While emitting each field entry into the SQL*Loader control file, the loader looks up each mapped stream field name in the row's value metadata (rm.indexOfValue). A negative index means a field listed in the step's field mapping does not exist in the actual incoming stream, so the control file cannot be built consistently.

Solutions

  1. Open the step mapping tab and re-select fields (click 'Get fields') so mappings match the current upstream stream.
  2. Rename the mapping entry or the upstream field so names match exactly (case- and whitespace-sensitive).
  3. Insert/fix a 'Select values' or upstream step so the missing field is actually produced.
  4. Preview rows immediately before the loader step to confirm the field is present, then re-save the step.

Example fix

// before: mapping references old name
<field><stream_name>cust_name</stream_name><table_column>NAME</table_column></field>
// after: matches renamed upstream field
<field><stream_name>customer_name</stream_name><table_column>NAME</table_column></field>
Defensive patterns

Strategy: validation

Validate before calling

// Java: confirm every mapped stream field exists in the incoming row meta
RowMetaInterface inputRowMeta = ...; // from getStepIOMeta / preview
for (String f : meta.getFieldStream()) {
  if (inputRowMeta.indexOfValue(f) < 0) {
    throw new IllegalStateException("Mapped stream field missing upstream: " + f);
  }
}

Try / catch

try {
  trans.execute(null);
} catch (KettleException e) {
  if (String.valueOf(e.getMessage()).startsWith("Could not find field")) {
    // log offending field name and re-open step mapping
  }
}

Prevention

When it happens

Trigger: meta.getFieldStream()[i] is not present in the input row metadata when getControlFileContents runs via createControlFile (indexOfValue returns < 0).

Common situations: An upstream step was renamed or deleted a field after the mapping was created; field names differ by case or whitespace; a 'Select values' step removed the column; the ktr was edited manually and the mapping drifted from the real 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/a1cfb7d69577e638. Report an issue: GitHub.

Appendix: source

Thrown at plugins/oracle-bulk-loader/impl/src/main/java/org/pentaho/di/trans/steps/orabulkloader/OraBulkLoader.java:262

      .append( Const.CR ).append( '(' );

    String[] streamFields = meta.getFieldStream();
    String[] tableFields = meta.getFieldTable();
    String[] dateMask = meta.getDateMask();

    if ( streamFields == null || streamFields.length == 0 ) {
      throw new KettleException( "No fields defined to load to database" );
    }

    for ( int i = 0; i < streamFields.length; i++ ) {
      if ( i != 0 ) {
        contents.append( ", " ).append( Const.CR );
      }
      contents.append( dm.quoteField( tableFields[i] ) );

      int pos = rm.indexOfValue( streamFields[i] );
      if ( pos < 0 ) {
        throw new KettleException( "Could not find field " + streamFields[i] + " in stream" );
      }
      ValueMetaInterface v = rm.getValueMeta( pos );
      switch ( v.getType() ) {
        case ValueMetaInterface.TYPE_STRING:
          if ( v.getLength() > 255 ) {
            contents.append( " CHAR(" ).append( v.getLength() ).append( ")" );
          } else {
            contents.append( " CHAR" );
          }
          break;
        case ValueMetaInterface.TYPE_INTEGER:
        case ValueMetaInterface.TYPE_NUMBER:
        case ValueMetaInterface.TYPE_BIGNUMBER:
          break;
        case ValueMetaInterface.TYPE_DATE:
          if ( OraBulkLoaderMeta.DATE_MASK_DATE.equals( dateMask[i] ) ) {
            contents.append( " DATE 'yyyy-mm-dd'" );
          } else if ( OraBulkLoaderMeta.DATE_MASK_DATETIME.equals( dateMask[i] ) ) {

View on GitHub (pinned to f3058517a1)