{"record":{"id":"fef197d9917ed81b","repo":"pentaho/pentaho-kettle","slug":"tableoutput-exception-fieldrequired","errorCode":null,"errorMessage":"TableOutput.Exception.FieldRequired","messagePattern":"TableOutput\\.Exception\\.FieldRequired","errorType":"exception","errorClass":"KettleStepException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/tableoutput/TableOutput.java","lineNumber":103,"sourceCode":"      data.outputRowMeta = getInputRowMeta().clone();\n      meta.getFields( getTransMeta().getBowl(), data.outputRowMeta, getStepname(), null, null, this, repository,\n        metaStore );\n\n      if ( !meta.specifyFields() ) {\n        // Just take the input row\n        data.insertRowMeta = getInputRowMeta().clone();\n      } else {\n\n        data.insertRowMeta = new RowMeta();\n\n        //\n        // Cache the position of the compare fields in Row row\n        //\n        data.valuenrs = new int[meta.getFieldDatabase().length];\n        for ( int i = 0; i < meta.getFieldDatabase().length; i++ ) {\n          data.valuenrs[i] = getInputRowMeta().indexOfValue( meta.getFieldStream()[i] );\n          if ( data.valuenrs[i] < 0 ) {\n            throw new KettleStepException( BaseMessages.getString(\n              PKG, \"TableOutput.Exception.FieldRequired\", meta.getFieldStream()[i] ) );\n          }\n        }\n\n        for ( int i = 0; i < meta.getFieldDatabase().length; i++ ) {\n          ValueMetaInterface insValue = getInputRowMeta().searchValueMeta( meta.getFieldStream()[i] );\n          if ( insValue != null ) {\n            ValueMetaInterface insertValue = insValue.clone();\n            insertValue.setName( meta.getFieldDatabase()[i] );\n            data.insertRowMeta.addValueMeta( insertValue );\n          } else {\n            throw new KettleStepException( BaseMessages.getString(\n              PKG, \"TableOutput.Exception.FailedToFindField\", meta.getFieldStream()[i] ) );\n          }\n        }\n      }\n    }\n","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/tableoutput/TableOutput.java#L85-L121","documentation":"In TableOutput.processRow(), before writing rows the step caches the index of each configured stream field in the incoming row. If a field named in 'Field to insert' (fieldStream) is not present in the input row (indexOfValue < 0), it throws KettleStepException with TableOutput.Exception.FieldRequired. This is a configuration/data-shape mismatch: the mapping references a field the stream does not deliver.","triggerScenarios":"processRow() receives a row whose RowMeta lacks one of the fields listed in the step's field mapping (meta.getFieldStream()[i]), typically on the first row after init; occurs whenever upstream steps are changed after the TableOutput mapping was configured.","commonSituations":"Renaming or deleting an upstream field without updating TableOutput's mapping; a Select Values step dropping the field; case-sensitive name mismatch between mapping and stream; reusing a saved transformation against a changed source table/query.","solutions":["Open the TableOutput step and correct 'Field to insert' mapping to match actual upstream fields","Use 'Get Fields' to rebuild the mapping from the incoming stream","Fix the upstream step (SQL/Select Values/CSV) so it emits the expected field name","Check field-name case and whitespace — matching is exact via indexOfValue"],"exampleFix":"// before\nString[] fieldStream = meta.getFieldStream(); // contains 'CUST_ID' but stream has 'custid'\n// after\nString[] fieldStream = Arrays.stream( meta.getFieldStream() )\n  .map( f -> getInputRowMeta().searchValueMeta( f ) != null ? f\n       : findCaseInsensitive( getInputRowMeta(), f ) )\n  .toArray( String[]::new );","handlingStrategy":"validation","validationCode":"// validate the mapping against the live input row before executing\nSet<String> streamFields = new HashSet<>( Arrays.asList( prevStepFields.getFieldNames() ) );\nfor ( String f : meta.getFieldStream() ) {\n  if ( !streamFields.contains( f ) ) {\n    throw new IllegalStateException( \"Mapped field missing from input stream: \" + f );\n  }\n}","typeGuard":"boolean mappingIsValid( RowMetaInterface rowMeta, TableOutputMeta meta ) {\n  return Arrays.stream( meta.getFieldStream() )\n    .allMatch( f -> rowMeta.indexOfValue( f ) >= 0 );\n}","tryCatchPattern":"try {\n  trans.startExecution();\n} catch ( KettleStepException e ) {\n  if ( e.getMessage().contains( \"TableOutput.Exception.FieldRequired\" ) ) {\n    // open TableOutput mapping and re-sync with upstream fields\n  } else { throw e; }\n}","preventionTips":["Run 'Get Fields' in the TableOutput dialog whenever upstream steps change","Preview upstream steps before executing the transformation","Keep field names case-consistent end to end","Avoid renaming fields with Select Values downstream of an existing mapping without updating it"],"tags":["kettle","table-output","row-metadata","field-mapping"],"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"}