{"record":{"id":"b0573f68e670ff83","repo":"pentaho/pentaho-kettle","slug":"normalisermeta-exception-unabletofindfield","errorCode":"NormaliserMeta.Exception.UnableToFindField","errorMessage":"NormaliserMeta.Exception.UnableToFindField","messagePattern":"NormaliserMeta\\.Exception\\.UnableToFindField","errorType":"exception","errorClass":"KettleStepException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/normaliser/NormaliserMeta.java","lineNumber":230,"sourceCode":"    // Then add the type field!\n    //\n    ValueMetaInterface typefield_value = new ValueMetaString( typeField );\n    typefield_value.setOrigin( name );\n    typefield_value.setLength( maxlen );\n    row.addValueMeta( typefield_value );\n\n    // Loop over the distinct list of fieldNorm[i]\n    // Add the new fields that need to be created.\n    // Use the same data type as the original fieldname...\n    //\n    for ( int i = 0; i < norm_occ.size(); i++ ) {\n      String normname = norm_occ.get( i );\n      String fieldname = field_occ.get( i );\n      ValueMetaInterface v = row.searchValueMeta( fieldname );\n      if ( v != null ) {\n        v = v.clone();\n      } else {\n        throw new KettleStepException( BaseMessages.getString( PKG, \"NormaliserMeta.Exception.UnableToFindField\", fieldname ) );\n      }\n      v.setName( normname );\n      v.setOrigin( name );\n      row.addValueMeta( v );\n    }\n\n    // Now remove all the normalized fields...\n    //\n    for ( int i = 0; i < normaliserFields.length; i++ ) {\n      int idx = row.indexOfValue( normaliserFields[i].getName() );\n      if ( idx >= 0 ) {\n        row.removeValueMeta( idx );\n      }\n    }\n  }\n\n  @Override\n  public String getXML() {","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/normaliser/NormaliserMeta.java#L212-L248","documentation":"NormaliserMeta.getFields() builds the output row by cloning each input field listed in the Normaliser step config and renaming it to the configured 'normalised' name. Before cloning it looks the field up in the incoming row via row.searchValueMeta(fieldname). If a configured field name does not exist in the incoming row stream, a KettleStepException is thrown with this localized message.","triggerScenarios":"Calling getFields (directly or via transformation row-layout resolution) when normaliserFields[i].getFieldValue() names a field absent from row (RowMetaInterface.searchValueMeta returns null).","commonSituations":"Upstream step renamed or removed the field; the Normaliser config references a field from a deleted hop; field name case/spelling mismatch; transformation edited after the Normaliser was configured; repository/XML metadata loaded from an older transformation version.","solutions":["Fix the Normaliser step configuration so 'Fieldname' matches an actual incoming field exactly (case-sensitive).","Verify the upstream step still produces the field; add or repair the hop/step that emits it.","Open the transformation and re-run 'Get Fields' on the Normaliser step to refresh the field list.","If the field is optional, add a Select values step upstream that guarantees the field exists."],"exampleFix":"// before (config XML references a stale field)\n<field><name>old_amount</name><norm>amount</norm></field>\n// after (matches upstream field)\n<field><name>amount</name><norm>amount</norm></field>","handlingStrategy":"validation","validationCode":"// Java, before configuring/running the step\nRowMetaInterface inputRowMeta = ...;\nfor (NormaliserField f : normaliserMeta.getNormaliserFields()) {\n  if (inputRowMeta.searchValueMeta(f.getFieldName()) == null) {\n    throw new IllegalStateException(\"Field not in incoming row: \" + f.getFieldName());\n  }\n}","typeGuard":"boolean fieldExists(RowMetaInterface row, String name) { return row != null && row.searchValueMeta(name) != null; }","tryCatchPattern":"try { stepMeta.getFields(rows, name, info, null, null, space); } catch (KettleStepException e) { log.error(\"Normaliser field missing: \" + e.getMessage(), e); }","preventionTips":["Use 'Get Fields' in Spoon to populate field names instead of typing them.","Re-check the Normaliser config after any upstream step rename/removal.","Keep field names case-consistent across steps.","Run the transformation preview frequently to catch row-layout drift early."],"tags":["kettle","pdi","row-metadata","field-not-found"],"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"}