stanfordnlp/CoreNLP · error · IllegalArgumentException

r must not be null!

Error message

r must not be null!

What it means

SimpleGoodTuring implements Simple Good-Turing smoothing from counts-of-counts arrays; the constructor validates its inputs up front and throws IllegalArgumentException if the r array (frequency values) is null. This fail-fast check prevents NullPointerExceptions deep in the smoothing computation.

Solutions

  1. Ensure r is populated (non-null, positive, ascending) before constructing
  2. Add a null/empty check at the data-loading site and fail there with a clearer message
  3. Check why the frequency array source returned null (missing file, empty parse)

Example fix

// before
SimpleGoodTuring sgt = new SimpleGoodTuring(r, n);
// after
if (r == null || r.length == 0) throw new IllegalStateException("frequency array not loaded");
SimpleGoodTuring sgt = new SimpleGoodTuring(r, n);
Defensive patterns

Strategy: validation

Validate before calling

if (r == null || r.length < 2) throw new IllegalStateException("frequency array r missing or too small");

Type guard

boolean hasValidR(int[] r) { return r != null && r.length >= 2 && Arrays.stream(r).allMatch(v -> v > 0); }

Try / catch

try {
  return new SimpleGoodTuring(r, n);
} catch (IllegalArgumentException e) {
  if (e.getMessage() != null && e.getMessage().contains("r must not be null")) {
    return defaultSmoothing(); // fall back to unsmoothed/add-k estimates
  }
  throw e;
}

Prevention

When it happens

Trigger: new SimpleGoodTuring(null, n) — passing a null r array, typically when frequency data failed to load or a variable was never initialized.

Common situations: Config/pipeline mistakes where the counts file wasn't read and arrays stayed null; refactors that dropped an array initialization; conditional data-loading that silently skipped population of r.

Related errors


AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10). Data as JSON: /api/errors/63d5197ed438b911. Report an issue: GitHub.

Appendix: source

Thrown at src/edu/stanford/nlp/stats/SimpleGoodTuring.java:47

  private double slope;
  private double intercept;
  private double[] z;
  private double[] logR;
  private double[] logZ;
  private double[] rStar;
  private double[] p;

  /**
   * Each instance of this class encapsulates the computation of the smoothing
   * for one probability distribution.  The constructor takes two arguments
   * which are two parallel arrays.  The first is an array of counts, which must
   * be positive and in ascending order.  The second is an array of
   * corresponding counts of counts; that is, for each i, n[i] represents the
   * number of types which occurred with count r[i] in the underlying
   * collection.  See the documentation for main() for a concrete example.
   */
  public SimpleGoodTuring(int[] r, int[] n) {
    if (r == null) throw new IllegalArgumentException("r must not be null!");
    if (n == null) throw new IllegalArgumentException("n must not be null!");
    if (r.length != n.length) throw new IllegalArgumentException("r and n must have same size!");
    if (r.length < MIN_INPUT) throw new IllegalArgumentException("r must have size >= " + MIN_INPUT + "!");
    this.r = new int[r.length];
    this.n = new int[n.length];
    System.arraycopy(r, 0, this.r, 0, r.length); // defensive copy
    System.arraycopy(n, 0, this.n, 0, n.length); // defensive copy
    this.rows = r.length;
    compute();
    validate(TOLERANCE);
  }

  /**
   * Returns the probability allocated to types not seen in the underlying
   * collection.
   */
  public double getProbabilityForUnseen() {
    return pZero;

View on GitHub (pinned to 1b7edd19c4)