stanfordnlp/CoreNLP · error · IllegalArgumentException

n must not be null!

Error message

n must not be null!

What it means

Same constructor validation as the r check: SimpleGoodTuring requires a non-null n array (counts of counts) and throws IllegalArgumentException immediately if it is null, since smoothing cannot proceed without it.

Solutions

  1. Ensure n is loaded and non-null before construction
  2. Validate both arrays at the loading site with a single check
  3. Fix the data source that returned null for the counts-of-counts

Example fix

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

Strategy: validation

Validate before calling

if (n == null || n.length < 2) throw new IllegalStateException("counts-of-counts array n missing or too small");

Type guard

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

Try / catch

try {
  return new SimpleGoodTuring(r, n);
} catch (IllegalArgumentException e) {
  if (e.getMessage() != null && e.getMessage().contains("n must not be null")) {
    return defaultSmoothing();
  }
  throw e;
}

Prevention

When it happens

Trigger: new SimpleGoodTuring(r, null) — the counts-of-counts array was never loaded or initialized.

Common situations: File/DB load failures leaving n null while r was populated; copy-paste errors initializing only one of the two arrays.

Related errors


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

Appendix: source

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

  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)