{"record":{"id":"460bc397932e7838","repo":"stanfordnlp/CoreNLP","slug":"this-point-should-never-be-reached","errorCode":null,"errorMessage":"This point should never be reached","messagePattern":"This point should never be reached","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/stats/Multinomial.java","lineNumber":65,"sourceCode":"  }\n\n  public double logProbabilityOf(E object) {\n    if (!parameters.keySet().contains(object)) {\n      throw new RuntimeException(\"Not a valid object for this multinomial!\");\n    }\n    return Math.log(parameters.getCount(object));\n  }\n\n  public E drawSample(Random random) {\n    double r = random.nextDouble();\n    double sum = 0.0;\n    for (E object : parameters.keySet()) {\n      sum += parameters.getCount(object);\n      if (sum  >= r) {\n        return object;\n      }\n    }\n    throw new RuntimeException(\"This point should never be reached\");\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Override\n  public boolean equals(Object o) {\n    if (!(o instanceof Multinomial)) { return false; }\n    Multinomial otherMultinomial = (Multinomial)o;\n    return parameters.equals(otherMultinomial.parameters);\n  }\n\n  private int hashCode = -1;\n  @Override\n  public int hashCode() {\n    if (hashCode == -1) {\n      hashCode = parameters.hashCode() + 17;\n    }\n    return hashCode;\n  }","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/stats/Multinomial.java#L47-L83","documentation":"drawSample walks the cumulative distribution and returns the first object where the running sum reaches the random draw r; if the loop finishes without the sum reaching r, the code throws, indicating the parameter distribution did not sum to at least r (in practice an invariant violation: counts not normalized or corrupted).","triggerScenarios":"Calling drawSample(Random) when the internal parameters do not sum to ~1.0 (e.g. the Multinomial was deserialized from an old version, or parameters were mutated); floating-point round-off in extreme cases where cumulative sum stays just below r near 1.0.","commonSituations":"Serialization/version drift leaving parameters unnormalized; manual edits to the parameters counter; sampling loops that repeatedly draw near 1.0 with under-normalized distributions.","solutions":["Construct Multinomial only via the normalizing constructor and avoid mutating its internal parameters","If you build parameters manually, normalize so the counts sum to 1.0 before sampling","Catch the exception and retry the draw as a defensive fallback in sampling code"],"exampleFix":"// before\nE sample = multinomial.drawSample(random);\n// after\nE sample;\ntry {\n  sample = multinomial.drawSample(random);\n} catch (RuntimeException e) {\n  sample = null; // distribution not normalized; rebuild the Multinomial\n}","handlingStrategy":"try-catch","validationCode":"double total = m.getParameters().totalCount();\nif (Math.abs(total - 1.0) > 1e-6) throw new IllegalStateException(\"multinomial not normalized: \" + total);","typeGuard":"boolean isNormalized(Multinomial<?> m) { return Math.abs(m.getParameters().totalCount() - 1.0) < 1e-6; }","tryCatchPattern":"try {\n  return m.drawSample(random);\n} catch (RuntimeException e) {\n  if (\"This point should never be reached\".equals(e.getMessage())) {\n    return lastKeyAsFallback(m); // or rebuild the multinomial\n  }\n  throw e;\n}","preventionTips":["Never mutate a Multinomial's parameters after construction","Always build via the normalizing constructor","Avoid deserializing multinomials across incompatible versions"],"tags":["java","statistics","sampling","invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}