pentaho/pentaho-kettle · error · KettleException
ClosureGenerator.Exception.ChildFieldNotFound
Error message
ClosureGenerator.Exception.ChildFieldNotFound
What it means
ClosureGenerator.processRow looks up the configured child-id field in the input row metadata via indexOfValue(meta.getChildIdFieldName()). If absent (index < 0), it throws a KettleException with this message. Same root cause as the parent-field variant but for the Child ID field setting.
Solutions
- Verify the Child ID field name in the dialog against the actual input fields
- Use 'Get Fields' to select from the real stream
- Fix upstream steps that renamed or removed the child field
- Preview input rows to confirm field presence
Example fix
// before Child ID field: child_id // after (stream field is childId) Child ID field: childId
Defensive patterns
Strategy: validation
Validate before calling
if (inputRowMeta.indexOfValue(childFieldName) < 0) {
throw new IllegalArgumentException("Child field " + childFieldName + " 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("ChildFieldNotFound")) {
// correct Child ID field in dialog
}
} Prevention
- Verify both parent and child fields in dialog before save
- Preview the input stream
- Keep upstream field names stable
When it happens
Trigger: Running the Closure Generator step when the 'Child ID field' configured in the step metadata is not present in the incoming rows.
Common situations: Misspelled child field name, upstream field renamed/deleted, mixing up parent and child field entries in the dialog.
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.ParentFieldNotFound
- 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/5ba5add87d77fc91.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/core/impl/src/main/java/org/pentaho/di/trans/steps/closure/ClosureGenerator.java:72
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 );
}
} else {
// Writing the rows back...
//
for ( Object current : data.map.keySet() ) {
data.parents = new HashMap<Object, Long>();View on GitHub (pinned to f3058517a1)