pentaho/pentaho-kettle · error · KettleException
ClosureGenerator.Exception.ParentFieldNotFound
Error message
ClosureGenerator.Exception.ParentFieldNotFound
What it means
ClosureGenerator.processRow looks up the configured parent-id field in the incoming row metadata via indexOfValue(meta.getParentIdFieldName()). If the field is absent from the input stream (index < 0), it throws a KettleException with this message. It means the Parent ID field configured on the step does not exist in the rows entering the step.
Solutions
- Open the Closure Generator dialog and verify the Parent ID field name matches the incoming stream exactly
- Use 'Get Fields' in the dialog to pick from actual upstream fields
- Check upstream steps for renames/deletions of the field
- Preview the input rows to confirm the field exists
Example fix
// before: dialog has parent_field Parent ID field: parent_field // after (stream field is parentId) Parent ID field: parentId
Defensive patterns
Strategy: validation
Validate before calling
// In a prior step or dialog check:
if (inputRowMeta.indexOfValue(parentFieldName) < 0) {
throw new IllegalArgumentException("Parent field " + parentFieldName + " missing from stream");
} Type guard
boolean hasField(RowMetaInterface rowMeta, String name) {
return name != null && rowMeta.indexOfValue(name) >= 0;
} Try / catch
try {
step.processRow();
} catch (KettleException e) {
if (e.getMessage().contains("ParentFieldNotFound")) {
// fix field mapping in dialog and restart transformation
}
} Prevention
- Always use 'Get Fields' in the step dialog
- Preview upstream rows before running
- Avoid renaming fields mid-pipeline without updating dependent steps
When it happens
Trigger: Running the Closure Generator step when the field named in 'Parent ID field' is not present in the input row layout — renamed upstream field, wrong field name configured, or wrong hop ordering.
Common situations: Renaming or removing the parent field in an earlier step, misspelling the field name in the dialog, connecting a different stream than intended.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- ClosureGenerator.Exception.ChildFieldNotFound
- AvroInput.Error.NoPathSet
- Calculator.Error.UnableFindField
- ConcatFields.Error.RemainingFieldNotFoundInputStream
- Could not find field
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/88018f5bebb1333e.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/core/impl/src/main/java/org/pentaho/di/trans/steps/closure/ClosureGenerator.java:67
Object[] rowData = getRow();
if ( rowData == null ) {
data.reading = false;
} else {
if ( first ) {
first = false;
// Create the output row metadata
//
data.outputRowMeta = getInputRowMeta().clone();
meta.getFields( getTransMeta().getBowl(), data.outputRowMeta, getStepname(), null, null, this, repository,
metaStore );
// Get indexes of parent and child field
//
data.parentIndex = getInputRowMeta().indexOfValue( meta.getParentIdFieldName() );
if ( data.parentIndex < 0 ) {
throw new KettleException( BaseMessages.getString(
PKG, "ClosureGenerator.Exception.ParentFieldNotFound" ) );
}
data.childIndex = getInputRowMeta().indexOfValue( meta.getChildIdFieldName() );
if ( data.childIndex < 0 ) {
throw new KettleException( BaseMessages.getString(
PKG, "ClosureGenerator.Exception.ChildFieldNotFound" ) );
}
data.parentValueMeta = getInputRowMeta().getValueMeta( data.parentIndex );
data.childValueMeta = getInputRowMeta().getValueMeta( data.childIndex );
}
// add values to the buffer...
//
Object parentId = rowData[ data.parentIndex ];
Object childId = rowData[ data.childIndex ];
data.map.put( childId, parentId );
}View on GitHub (pinned to f3058517a1)