{"record":{"id":"75371e09acfda4ae","repo":"pentaho/pentaho-kettle","slug":"denormalisermeta-exception-requiredkeyfield","errorCode":"DenormaliserMeta.Exception.RequiredKeyField","errorMessage":"DenormaliserMeta.Exception.RequiredKeyField","messagePattern":"DenormaliserMeta\\.Exception\\.RequiredKeyField","errorType":"exception","errorClass":"KettleStepException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/denormaliser/DenormaliserMeta.java","lineNumber":169,"sourceCode":"\n    allocate( sizegroup, nrfields );\n  }\n\n  @Override\n  public void getFields( Bowl bowl, RowMetaInterface row, String name, RowMetaInterface[] info, StepMeta nextStep,\n    VariableSpace space, Repository repository, IMetaStore metaStore ) throws KettleStepException {\n\n    // Remove the key value (there will be different entries for each output row)\n    //\n    if ( keyField != null && keyField.length() > 0 ) {\n      int idx = row.indexOfValue( keyField );\n      if ( idx < 0 ) {\n        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","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/denormaliser/DenormaliserMeta.java#L151-L187","documentation":"DenormaliserMeta.getFields requires a key field (the field whose distinct values group the rows). When the keyField setting is null or an empty string, the step cannot build its grouping logic and throws a KettleStepException with this message instead of attempting a lookup.","triggerScenarios":"getFields executes with keyField == null || keyField.length() == 0, i.e. the Denormaliser step was never given a grouping key field (the else-branch of the keyField check).","commonSituations":"Freshly dropped Denormaliser step left unconfigured; metadata injection mapping omitted the key field; a saved transformation lost the key field setting after a schema/upgrade issue.","solutions":["Open the Denormaliser step dialog and set the 'key field' to the grouping column.","If using metadata injection, map the key field target in the injection metadata.","Re-apply the step configuration from a working version of the transformation."],"exampleFix":"// before\n<key_field></key_field>\n// after\n<key_field>customer_id</key_field>","handlingStrategy":"validation","validationCode":"if (denormMeta.getKeyField() == null || denormMeta.getKeyField().isEmpty()) {\n  throw new IllegalArgumentException(\"Denormaliser key field must be configured\");\n}","typeGuard":null,"tryCatchPattern":"try { transMeta.getFields(...); } catch (KettleStepException e) { log.error(\"Denormaliser unconfigured: {}\", e.getMessage()); }","preventionTips":["Always configure the grouping key field when adding a Denormaliser step.","Include the key field target in metadata injection mappings.","Run transformation verification (Ctrl+V in Spoon) before execution."],"tags":["denormaliser","missing-configuration","stream-metadata"],"backgroundTag":"missing-required-config-field","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"}