{"record":{"id":"fc05d1a1bffe99b3","repo":"pentaho/pentaho-kettle","slug":"synchronizeaftermerge-exception-fieldrequired-updatestream-i","errorCode":null,"errorMessage":"SynchronizeAfterMerge.Exception.FieldRequired (updateStream[i])","messagePattern":"SynchronizeAfterMerge\\.Exception\\.FieldRequired \\(updateStream\\[i\\]\\)","errorType":"exception","errorClass":"KettleStepException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/synchronizeaftermerge/SynchronizeAfterMerge.java","lineNumber":750,"sourceCode":"        ValueMetaInterface insValue = data.insertRowMeta.searchValueMeta( meta.getUpdateLookup()[i] );\n        if ( insValue == null ) { // Don't add twice!\n          // we already checked that this value exists so it's probably safe to ignore lookup failure...\n          ValueMetaInterface insertValue = data.inputRowMeta.searchValueMeta( meta.getUpdateStream()[i] ).clone();\n          insertValue.setName( meta.getUpdateLookup()[i] );\n          data.insertRowMeta.addValueMeta( insertValue );\n        } else {\n          throw new KettleStepException( BaseMessages.getString( PKG,\n            \"SynchronizeAfterMerge.Error.SameColumnInsertedTwice\", insValue.getName() ) );\n        }\n      }\n\n      // Cache the position of the compare fields in Row row\n      //\n      data.valuenrs = new int[meta.getUpdateLookup().length];\n      for (int i = 0; i < meta.getUpdateLookup().length; i++) {\n        data.valuenrs[i] = data.inputRowMeta.indexOfValue( meta.getUpdateStream()[i] );\n        if ( data.valuenrs[i] < 0 ) { // couldn't find field!\n          throw new KettleStepException( BaseMessages.getString( PKG, \"SynchronizeAfterMerge.Exception.FieldRequired\",\n            meta.getUpdateStream()[i] ) );\n        }\n        if ( log.isDebug() ) {\n          logDebug( BaseMessages.getString( PKG, \"SynchronizeAfterMerge.Log.FieldHasDataNumbers\", meta\n            .getUpdateStream()[i] ) + data.valuenrs[i] );\n        }\n      }\n\n      if ( !meta.istablenameInField() ) {\n        // Prepare Lookup statement\n        if ( meta.isPerformLookup() ) {\n          data.lookupStatement = data.preparedStatements.get( data.realSchemaTable + \"lookup\" );\n          if ( data.lookupStatement == null ) {\n            String sql = getLookupStatement( data.inputRowMeta );\n            if ( log.isDebug() ) {\n              logDebug( \"Preparation of the lookup SQL statement : \" + sql );\n            }\n","sourceCodeStart":732,"sourceCodeEnd":768,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/synchronizeaftermerge/SynchronizeAfterMerge.java#L732-L768","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nupdateStream: total_amt (upstream now emits total_amount) -> indexOfValue = -1 -> throw\n// after\nupdateStream: total_amount\n// or upstream Select values: rename total_amount -> total_amt","handlingStrategy":"validation","validationCode":"var m = stepMeta.getStepMetaInterface();\nvar prev = transMeta.getPrevStepFields(stepMeta);\nfor (var i = 0; i < m.getUpdateStream().length; i++) {\n  if (prev.indexOfValue(m.getUpdateStream()[i]) < 0) throw new Error(\"Update stream field missing: \" + m.getUpdateStream()[i]);\n}","typeGuard":"function allFieldsExist(names, rowMeta) { return names.every(function(n) { return rowMeta.indexOfValue(n) >= 0; }); }","tryCatchPattern":"try { trans.execute(...); } catch (KettleException e) { if (e.getMessage().contains(\"FieldRequired\")) { log.error(\"Update stream field missing: \" + e.getMessage()); } else throw e; }","preventionTips":["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"],"tags":["kettle","field-not-found","mapping","step-configuration"],"backgroundTag":"resource-not-found","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}