{"record":{"id":"24c5c605992519e9","repo":"pentaho/pentaho-kettle","slug":"second-meta-data-meta2-is-null-please-check-one-of-the","errorCode":null,"errorMessage":" : Second meta data (meta2) is null, please check one of the previous steps.","messagePattern":" : Second meta data \\(meta2\\) is null, please check one of the previous steps\\.","errorType":"exception","errorClass":"KettleValueException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/row/value/ValueMetaBase.java","lineNumber":3792,"sourceCode":"  }\n\n  /**\n   * Compare 2 values of the same data type\n   *\n   * @param data1\n   *          the first value\n   * @param meta2\n   *          the second value's metadata\n   * @param data2\n   *          the second value\n   * @return 0 if the values are equal, -1 if data1 is smaller than data2 and +1 if it's larger.\n   * @throws KettleValueException\n   *           In case we get conversion errors\n   */\n  @Override\n  public int compare( Object data1, ValueMetaInterface meta2, Object data2 ) throws KettleValueException {\n    if ( meta2 == null ) {\n      throw new KettleValueException( toStringMeta()\n          + \" : Second meta data (meta2) is null, please check one of the previous steps.\" );\n    }\n\n    try {\n      // Before we can compare data1 to data2 we need to make sure they have the\n      // same data type etc.\n      //\n      if ( getType() == meta2.getType() ) {\n        if ( getStorageType() == meta2.getStorageType() ) {\n          return compare( data1, data2 );\n        }\n\n        // Convert the storage type to compare the data.\n        //\n        switch ( getStorageType() ) {\n          case STORAGE_TYPE_NORMAL:\n            return compare( data1, meta2.convertToNormalStorageType( data2 ) );\n          case STORAGE_TYPE_BINARY_STRING:","sourceCodeStart":3774,"sourceCodeEnd":3810,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/row/value/ValueMetaBase.java#L3774-L3810","documentation":"ValueMetaBase.compare(Object, ValueMetaInterface, Object) requires the second value's metadata (meta2) to convert data2 before comparing. When meta2 is null it throws this KettleValueException, explicitly hinting that an upstream step produced incomplete row metadata. It is a defensive null check for broken pipeline metadata flow.","triggerScenarios":"Calling compare(data1, null, data2) — directly or through sort/merge/stream-lookup code paths that pass a ValueMetaInterface obtained from row meta where the field lookup returned null (e.g. searchValueMeta() on a missing field name).","commonSituations":"A previous step in a transformation was removed/renamed so a field's metadata vanished; plugins that build RowMeta without adding all fields; passing null ValueMeta into RowSet comparison utilities; incorrect index into a row's value meta array.","solutions":["Check the previous steps: ensure the field's metadata exists in the RowMetaInterface before comparing (rowMeta.indexOfValue / searchValueMeta != null).","Pass a valid non-null ValueMetaInterface for meta2 (e.g. clone or construct one matching the data).","Add a null-guard before invoking compare and log which field/step produced missing metadata.","Open and re-save the transformation so hop metadata is regenerated if a stale/corrupt ktr references deleted fields."],"exampleFix":"// before\nint cmp = meta1.compare(data1, rowMeta.searchValueMeta(\"amount\"), data2); // may be null\n\n// after\nValueMetaInterface meta2 = rowMeta.searchValueMeta(\"amount\");\nif (meta2 == null) {\n  throw new KettleValueException(\"Field 'amount' missing from previous step metadata\");\n}\nint cmp = meta1.compare(data1, meta2, data2);","handlingStrategy":"type-guard","validationCode":"ValueMetaInterface meta2 = rowMeta.searchValueMeta(fieldName);\nif (meta2 == null) {\n  throw new KettleValueException(\"Field '\" + fieldName + \"' missing in incoming row metadata\");\n}\nint cmp = meta1.compare(data1, meta2, data2);","typeGuard":"boolean canCompare(ValueMetaInterface m1, ValueMetaInterface m2) {\n  return m1 != null && m2 != null;\n}","tryCatchPattern":"try { cmp = meta1.compare(data1, meta2, data2); } catch (KettleValueException e) {\n  if (e.getMessage().contains(\"meta2) is null\")) {\n    logger.logMinimal(\"Upstream step dropped field metadata; halting\");\n  }\n  throw e;\n}","preventionTips":["Always null-check searchValueMeta() results before use.","Keep field names consistent between steps; avoid hard-coded renames.","Re-open and re-save transformations after upstream step changes.","Use transMeta.checkSteps() to catch missing-field references before running."],"tags":["pdi","kettle","null-argument","row-metadata"],"backgroundTag":"null-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"}