{"record":{"id":"ec71f629b14cc9d3","repo":"pentaho/pentaho-kettle","slug":"denormalisermeta-exception-requiredtargetfieldname","errorCode":"DenormaliserMeta.Exception.RequiredTargetFieldName","errorMessage":"DenormaliserMeta.Exception.RequiredTargetFieldName","messagePattern":"DenormaliserMeta\\.Exception\\.RequiredTargetFieldName","errorType":"exception","errorClass":"KettleStepException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/denormaliser/DenormaliserMeta.java","lineNumber":182,"sourceCode":"        throw new KettleStepException( BaseMessages.getString(\n          PKG, \"DenormaliserMeta.Exception.UnableToLocateKeyField\", keyField ) );\n      }\n      row.removeValueMeta( idx );\n    } else {\n      throw new KettleStepException( BaseMessages.getString( PKG, \"DenormaliserMeta.Exception.RequiredKeyField\" ) );\n    }\n\n    // Remove all field value(s) (there will be different entries for each output row)\n    //\n    for ( int i = 0; i < denormaliserTargetField.length; i++ ) {\n      String fieldname = denormaliserTargetField[i].getFieldName();\n      if ( fieldname != null && fieldname.length() > 0 ) {\n        int idx = row.indexOfValue( fieldname );\n        if ( idx >= 0 ) {\n          row.removeValueMeta( idx );\n        }\n      } else {\n        throw new KettleStepException( BaseMessages.getString(\n          PKG, \"DenormaliserMeta.Exception.RequiredTargetFieldName\", ( i + 1 ) + \"\" ) );\n      }\n    }\n\n    // Re-add the target fields\n    for ( int i = 0; i < denormaliserTargetField.length; i++ ) {\n      DenormaliserTargetField field = denormaliserTargetField[i];\n      try {\n        ValueMetaInterface target =\n          ValueMetaFactory.createValueMeta( field.getTargetName(), field.getTargetType() );\n        target.setOrigin( name );\n        target.setConversionMask( field.getTargetFormat() );\n        target.setLength( field.getTargetLength(), field.getTargetPrecision() );\n        target.setCurrencySymbol( field.getTargetCurrencySymbol() );\n        target.setDecimalSymbol( field.getTargetDecimalSymbol() );\n        target.setGroupingSymbol( field.getTargetGroupingSymbol() );\n        row.addValueMeta( target );\n      } catch ( Exception e ) {","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/denormaliser/DenormaliserMeta.java#L164-L200","documentation":"In DenormaliserMeta.getFields, every configured target field must have a non-empty field name, because the step removes those source columns from the row before re-adding the denormalized (pivoted) targets. If the i-th target field's name is null or empty, a KettleStepException identifies the offending entry by ordinal (i+1).","triggerScenarios":"getFields iterates denormaliserTargetField and encounters an entry whose getFieldName() is null or \"\" — thrown with the 1-based index of the bad entry.","commonSituations":"A partially filled target-field row in the Denormaliser dialog (name left blank but other settings entered); metadata injection mapping that skips a field name; programmatic construction of DenormaliserMeta with a default-constructed target field.","solutions":["Open the Denormaliser dialog and fill in the missing target field name (the message tells you which entry number is blank).","Delete blank/unused rows from the target fields table.","If injecting metadata, ensure every target-field row includes a non-empty field name.","In code, always call setFieldName(...) on each DenormaliserTargetField before use."],"exampleFix":"// before\ntargets[2].setFieldName(null);\n// after\ntargets[2].setFieldName(\"amount\");","handlingStrategy":"validation","validationCode":"for (int i = 0; i < targets.length; i++) {\n  if (targets[i].getFieldName() == null || targets[i].getFieldName().isEmpty()) {\n    throw new IllegalArgumentException(\"Target field \" + (i + 1) + \" has no name\");\n  }\n}","typeGuard":null,"tryCatchPattern":"try { transMeta.getFields(...); } catch (KettleStepException e) { log.error(\"Denormaliser target field #? blank: {}\", e.getMessage()); }","preventionTips":["Fill in every column of the target-fields grid or delete unused rows.","Validate metadata injection mappings cover field names for all rows.","Set fieldName programmatically whenever constructing DenormaliserTargetField objects."],"tags":["denormaliser","missing-configuration","validation"],"backgroundTag":"missing-required-argument","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"}