pentaho/pentaho-kettle · error · KettleStepException
SynchronizeAfterMerge.Exception.FieldRequired…
Error message
SynchronizeAfterMerge.Exception.FieldRequired (updateStream[i])
What it means
The step resolves each 'Update stream' field (the stream-side field whose value is written to the table) to an index in the input row. If updateStream[i] is not present in the incoming RowMeta, processRow() throws KettleStepException FieldRequired(updateStream[i]). This guards against writing from a nonexistent field during INSERT/UPDATE generation.
Solutions
- Re-open the step and re-pick each 'Update stream' field from the field dropdown so names match the incoming stream
- Add a 'Select values' rename step upstream to recreate the expected field name
- Verify with preview on the previous step that the field is still produced at runtime
- Check for trailing whitespace or case mismatches in manually typed field names
Example fix
// before updateStream: total_amt (upstream now emits total_amount) -> indexOfValue = -1 -> throw // after updateStream: total_amount // or upstream Select values: rename total_amount -> total_amt
Defensive patterns
Strategy: validation
Validate before calling
var m = stepMeta.getStepMetaInterface();
var prev = transMeta.getPrevStepFields(stepMeta);
for (var i = 0; i < m.getUpdateStream().length; i++) {
if (prev.indexOfValue(m.getUpdateStream()[i]) < 0) throw new Error("Update stream field missing: " + m.getUpdateStream()[i]);
} Type guard
function allFieldsExist(names, rowMeta) { return names.every(function(n) { return rowMeta.indexOfValue(n) >= 0; }); } Try / catch
try { trans.execute(...); } catch (KettleException e) { if (e.getMessage().contains("FieldRequired")) { log.error("Update stream field missing: " + e.getMessage()); } else throw e; } Prevention
- Use 'Get Fields' to populate the mapping grid
- Re-validate the step after any upstream rename/delete
- Keep upstream schema changes and step mappings in the same commit/change
- Preview input rows before execution
When it happens
Trigger: A field named in the 'Update stream' column of the mapping grid is missing from the input stream: renamed/deleted upstream, wrong casing, or the step was moved behind a filter/select that dropped the field.
Common situations: Schema drift between environments; removing a calculated field upstream after the mapping was configured; typo when typing field names manually into the grid instead of picking from the dropdown.
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
- MappingMeta.Exception.UnableToFindField
- SynchronizeAfterMerge.Exception.FieldRequired (keyStream[i])
- SynchronizeAfterMerge.Exception.FieldRequired…
- ColumnExists.Exception.CouldnotFindField
- CombinationLookup.Exception.FieldNotFound
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/fc05d1a1bffe99b3.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/synchronizeaftermerge/SynchronizeAfterMerge.java:750
ValueMetaInterface insValue = data.insertRowMeta.searchValueMeta( meta.getUpdateLookup()[i] );
if ( insValue == null ) { // Don't add twice!
// we already checked that this value exists so it's probably safe to ignore lookup failure...
ValueMetaInterface insertValue = data.inputRowMeta.searchValueMeta( meta.getUpdateStream()[i] ).clone();
insertValue.setName( meta.getUpdateLookup()[i] );
data.insertRowMeta.addValueMeta( insertValue );
} else {
throw new KettleStepException( BaseMessages.getString( PKG,
"SynchronizeAfterMerge.Error.SameColumnInsertedTwice", insValue.getName() ) );
}
}
// Cache the position of the compare fields in Row row
//
data.valuenrs = new int[meta.getUpdateLookup().length];
for (int i = 0; i < meta.getUpdateLookup().length; i++) {
data.valuenrs[i] = data.inputRowMeta.indexOfValue( meta.getUpdateStream()[i] );
if ( data.valuenrs[i] < 0 ) { // couldn't find field!
throw new KettleStepException( BaseMessages.getString( PKG, "SynchronizeAfterMerge.Exception.FieldRequired",
meta.getUpdateStream()[i] ) );
}
if ( log.isDebug() ) {
logDebug( BaseMessages.getString( PKG, "SynchronizeAfterMerge.Log.FieldHasDataNumbers", meta
.getUpdateStream()[i] ) + data.valuenrs[i] );
}
}
if ( !meta.istablenameInField() ) {
// Prepare Lookup statement
if ( meta.isPerformLookup() ) {
data.lookupStatement = data.preparedStatements.get( data.realSchemaTable + "lookup" );
if ( data.lookupStatement == null ) {
String sql = getLookupStatement( data.inputRowMeta );
if ( log.isDebug() ) {
logDebug( "Preparation of the lookup SQL statement : " + sql );
}
View on GitHub (pinned to f3058517a1)