pentaho/pentaho-kettle · error · KettleStepException

Please set a field name for all field(s) that have 'null'.

Error message

Please set a field name for all field(s) that have 'null'.

What it means

BaseStep.putRow() validates outgoing row metadata unless allowEmptyFieldNamesAndTypes is set: if any ValueMetaInterface has a blank name, it throws KettleStepException 'Please set a field name for all field(s) that have null.' This guards downstream steps and serialization from anonymous fields (BACKLOG-18004).

Solutions

  1. Set a name on every ValueMetaInterface before putRow (vmi.setName("...")).
  2. Fix upstream metadata (Select Values / Calculator / UDJC) so renamed/derived fields always have names.
  3. Set allowEmptyFieldNamesAndTypes(true) on the step only if blank names are intentionally acceptable.
  4. In the input step, supply a name for columns whose header is blank.

Example fix

// before
rowMeta.addValueMeta(new ValueMetaString(""));
// after
rowMeta.addValueMeta(new ValueMetaString("computed_field"));
Defensive patterns

Strategy: validation

Validate before calling

for (ValueMetaInterface vmi : rowMeta.getValueMetaList()) {
  if (vmi.getName() == null || vmi.getName().trim().isEmpty())
    throw new IllegalStateException("Unnamed output field: set a name before putRow");
}

Try / catch

try { putRow(rowMeta, row); }
catch (KettleStepException e) { if (e.getMessage().contains("field name")) { nameUnnamedFields(rowMeta); putRow(rowMeta, row); } else throw e; }

Prevention

When it happens

Trigger: A step calls putRow(rowMeta, row) where rowMeta.getValueMetaList() contains a value meta whose getName() is null/blank — e.g. fields added with new ValueMetaString("") or null, or select/merge logic producing unnamed columns.

Common situations: User-defined Java/JavaScript steps emitting computed fields without naming them; Select Values or calculator producing empty field names; reading broken input files where a header cell is empty.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/step/BaseStep.java:1254

  }


  /**
   * putRow is used to copy a row, to the alternate rowset(s) This should get priority over everything else!
   * (synchronized) If distribute is true, a row is copied only once to the output rowsets, otherwise copies are sent to
   * each rowset!
   *
   * @param row The row to put to the destination rowset(s).
   * @throws KettleStepException
   */
  @Override
  public void putRow( RowMetaInterface rowMeta, Object[] row ) throws KettleStepException {
    if ( rowMeta != null ) {
      if ( !allowEmptyFieldNamesAndTypes ) {
        // check row meta for empty field name (BACKLOG-18004)
        for ( ValueMetaInterface vmi : rowMeta.getValueMetaList() ) {
          if ( StringUtils.isBlank( vmi.getName() ) ) {
            throw new KettleStepException( "Please set a field name for all field(s) that have 'null'." );
          }
          if ( vmi.getType() <= 0 ) {
            throw new KettleStepException( "Please set a value for the missing field(s) type." );
          }
        }
      }
    }
    getRowHandler().putRow( rowMeta, row );
  }

  private void handlePutRow( RowMetaInterface rowMeta, Object[] row ) throws KettleStepException {
    // Are we pausing the step? If so, stall forever...
    //
    while ( paused.get() && !stopped.get() ) {
      try {
        Thread.sleep( 1 );
      } catch ( InterruptedException e ) {
        throw new KettleStepException( e );

View on GitHub (pinned to f3058517a1)