{"record":{"id":"a1db2bf896f3af23","repo":"pentaho/pentaho-kettle","slug":"strings-must-not-be-null","errorCode":null,"errorMessage":"Strings must not be null","messagePattern":"Strings must not be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"warning","filePath":"core/src/main/java/org/pentaho/di/core/util/PentahoJaroWinklerDistance.java","lineNumber":86,"sourceCode":"   * distance.apply(\"hippo\", \"elephant\") = 0.44\n   * distance.apply(\"hippo\", \"zzzzzzzz\") = 0.0\n   * distance.apply(\"hello\", \"hallo\")    = 0.88\n   * distance.apply(\"ABC Corporation\", \"ABC Corp\") = 0.93\n   * distance.apply(\"D N H Enterprises Inc\", \"D &amp; H Enterprises, Inc.\") = 0.95\n   * distance.apply(\"My Gym Children's Fitness Center\", \"My Gym. Childrens Fitness\") = 0.92\n   * distance.apply(\"PENNSYLVANIA\", \"PENNCISYLVNIA\")    = 0.88\n   * </pre>\n   *\n   * @param left the first String, must not be null\n   * @param right the second String, must not be null\n   * @return result distance\n   * @throws IllegalArgumentException if either String input {@code null}\n   */\n  public void apply( final CharSequence left, final CharSequence right ) {\n    final double defaultScalingFactor = 0.1;\n\n    if ( left == null || right == null ) {\n      throw new IllegalArgumentException( \"Strings must not be null\" );\n    }\n\n    final int[] mtp = matches( left, right );\n    final double m = mtp[0];\n    if ( m == 0 ) {\n      j = 0D;\n      jw = 0D;\n    } else {\n      j = ( ( m / left.length() + m / right.length() + ( m - mtp[1] ) / m ) ) / 3;\n      jw = j < 0.7D ? j : j + Math.min( defaultScalingFactor, 1D / mtp[3] ) * mtp[2] * ( 1D - j );\n    }\n  }\n\n  /**\n   * This method returns the Jaro-Winkler string matches, transpositions, prefix, max array.\n   *\n   * @param first the first string to be matched\n   * @param second the second string to be matched","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/util/PentahoJaroWinklerDistance.java#L68-L104","documentation":"PentahoJaroWinklerDistance.apply throws an IllegalArgumentException when either of the two CharSequences being compared is null. The Jaro/Jaro-Winkler similarity algorithm requires two non-null strings; null inputs are a caller contract violation rather than a data problem.","triggerScenarios":"Calling apply(null, s), apply(s, null) or apply(null, null), directly or indirectly through getJaro_Similitude / getJaroWinkler_Similitude with a null operand (typically a null field value from a data row).","commonSituations":"Fuzzy-matching / dedup steps feeding null column values (e.g. missing address or name fields) into the similarity calculator without a prior null check.","solutions":["Null-check both strings before calling apply or the similitude helpers.","Treat null as empty string (\"\" ) when a null field means 'no value' for your matching logic.","If null should score as zero similarity, short-circuit in your own wrapper: if either is null, return 0."],"exampleFix":"// before\ndouble score = dist.getJaroWinkler_Similitude(row.getString(\"name\"), refName);\n// after\nString name = row.getString(\"name\");\ndouble score = (name == null || refName == null) ? 0.0 : dist.getJaroWinkler_Similitude(name, refName);","handlingStrategy":"type-guard","validationCode":"boolean comparable = (left != null && right != null);","typeGuard":"boolean isNonNullString(CharSequence cs) { return cs != null; }","tryCatchPattern":"try {\n  score = dist.getJaroWinkler_Similitude(a, b);\n} catch (IllegalArgumentException e) {\n  score = 0.0; // treat null as zero similarity\n}","preventionTips":["Null-check row field values before any string-similarity computation.","Normalize nulls to empty strings in a preprocessing step.","Write a wrapper utility that encodes your null policy once."],"tags":["null","string-similarity","illegal-argument"],"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"}