pentaho/pentaho-kettle · error · KettleStepException

Delete.Exception.FieldRequired

Delete.Exception.FieldRequired

Error message

Delete.Exception.FieldRequired

What it means

The Delete step locates each configured key field in the incoming row to build the WHERE clause for the DELETE statement. When a key field is missing from the input row — and its condition is not IS NULL / IS NOT NULL (which need no value) — the step throws this KettleStepException naming the missing field.

Solutions

  1. Correct the key field name in the Delete step to match an actual field in the input stream.
  2. Add the missing key field upstream (Select values / previous step output) before the Delete step.
  3. If the key is intentionally value-less, change its condition to 'IS NULL' or 'IS NOT NULL' so no field value is required.
  4. Inspect the incoming row layout (input step -> Show output fields) and fix case-sensitive mismatches.

Example fix

// before: key stream 'id' not in stream
Lookup key: id = =
// after
Lookup key: customer_id = =
Defensive patterns

Strategy: validation

Validate before calling

for (DeleteMeta.KeyField kf : meta.getKeyFields()) {
  boolean condNeedsValue = !"IS NULL".equalsIgnoreCase(kf.getKeyCondition())
      && !"IS NOT NULL".equalsIgnoreCase(kf.getKeyCondition());
  if (condNeedsValue && getInputRowMeta().indexOfValue(kf.getKeyStream()) < 0)
    throw new IllegalArgumentException("Missing Delete key field: "+kf.getKeyStream());
}

Type guard

boolean keyNeedsField(String condition){
  return !"IS NULL".equalsIgnoreCase(condition) && !"IS NOT NULL".equalsIgnoreCase(condition);
}

Try / catch

try { processRow(); }
catch (KettleStepException e) {
  logError("Delete key field missing: " + e.getMessage(), e);
  setErrors(1); stopAll(true);
}

Prevention

When it happens

Trigger: processRow runs while meta.getKeyFields()[i].getKeyStream() names a field not present in getInputRowMeta(), with any key condition other than 'IS NULL' or 'IS NOT NULL'.

Common situations: Upstream step renamed/removed the key field; typo in the key stream name; key condition configured as '=' while the field never arrives; wrong input stream connected in a multi-input branch.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — 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/79e0d037fa5f9d1a. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/delete/Delete.java:122

              meta.getDatabaseMeta().getQuotedSchemaTableCombination(
                      environmentSubstitute( meta.getSchemaName() ), environmentSubstitute( meta.getTableName() ) );

      // lookup the values!
      if ( log.isDetailed() ) {
        logDetailed( BaseMessages.getString( PKG, "Delete.Log.CheckingRow" ) + getInputRowMeta().getString( r ) );
      }

      // TODO: maybe handle if the fields in lookupFields are null
      int len = meta.getKeyFields().length;
      data.keynrs = new int[len];
      data.keynrs2 = new int[len];
      for ( int i = 0; i < len; i++ ) {
        data.keynrs[i] = getInputRowMeta().indexOfValue( meta.getKeyFields()[i].getKeyStream() );
        if ( data.keynrs[i] < 0 && // couldn't find field!
                !"IS NULL".equalsIgnoreCase( meta.getKeyFields()[i].getKeyCondition() ) && // No field needed!
                !"IS NOT NULL".equalsIgnoreCase( meta.getKeyFields()[i].getKeyCondition() ) // No field needed!
        ) {
          throw new KettleStepException( BaseMessages.getString( PKG, "Delete.Exception.FieldRequired",
                  meta.getKeyFields()[i].getKeyStream() ) );
        }

        data.keynrs2[i] = ( meta.getKeyFields()[i].getKeyStream2() != null
                && meta.getKeyFields()[i].getKeyStream2().length() > 0 )
                ? getInputRowMeta().indexOfValue( meta.getKeyFields()[i].getKeyStream2() ) : -1;
        if ( data.keynrs2[i] < 0 && // couldn't find field!
                "BETWEEN".equalsIgnoreCase( meta.getKeyFields()[i].getKeyCondition() ) // 2 fields needed!
        ) {
          throw new KettleStepException( BaseMessages.getString( PKG, "Delete.Exception.FieldRequired",
                  meta.getKeyFields()[i].getKeyStream2() ) );
        }

        if ( log.isDebug() ) {
          logDebug( BaseMessages.getString( PKG, "Delete.Log.FieldInfo",
                  meta.getKeyFields()[i].getKeyStream() ) + data.keynrs[i] );
        }
      }

View on GitHub (pinned to f3058517a1)