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
- Correct the key field name in the Delete step to match an actual field in the input stream.
- Add the missing key field upstream (Select values / previous step output) before the Delete step.
- If the key is intentionally value-less, change its condition to 'IS NULL' or 'IS NOT NULL' so no field value is required.
- 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
- Verify key field names against the input row layout before running.
- Use IS NULL / IS NOT NULL conditions when no field value is needed.
- Fix upstream renames before the Delete step.
- Check the correct input stream is connected on multi-input transforms.
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
- Calculator.Error.NoNameField
- Can not find field [ ] in the input stream!
- ChangeFileEncoding.Error.FilenameFieldMissing
- ChangeFileEncoding.Error.TargetFilenameFieldMissing
- ChangeFileEncoding.Exception.CouldnotFindField
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)