stanfordnlp/CoreNLP · error · RuntimeException

begin and end are equal

Error message

begin and end are equal 

What it means

Third variant of the 'begin and end are equal' invariant, for day durations P##D: when the dayRange parsed from the val is 0, start and end both equal the document time and getRange throws RuntimeException.

Solutions

  1. Fix upstream annotation to not emit P0D
  2. Treat P0D as a point at documentTime.getDate()
  3. Catch RuntimeException and build a zero-width Pair around documentTime
  4. Pre-validate with val.matches("P0+D")

Example fix

// before
Pair<Calendar,Calendar> range = timex.getRange(documentTime);
// after
if (timex.val().matches("P0+D")) {
  Calendar now = documentTime.getDate();
  Pair<Calendar,Calendar> range = new Pair<>(now, now);
} else {
  Pair<Calendar,Calendar> range = timex.getRange(documentTime);
}
Defensive patterns

Strategy: validation

Validate before calling

if (timex.val() != null && timex.val().matches("P0+D")) { handleAsPoint(); }

Try / catch

try { range = timex.getRange(docTime); } catch (RuntimeException e) { range = new Pair<>(docTime.getDate(), docTime.getDate()); }

Prevention

When it happens

Trigger: Calling getRange(documentTime) on a Timex val matching P\\d+D with 0 days (e.g. 'P0D').

Common situations: Zero-day durations appearing in TimeML annotations or produced by a misconfigured normalizer.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/edu/stanford/nlp/time/Timex.java:513

      int dayRange = Integer.parseInt(this.val.substring(1, this.val.length() - 1));

      // in the future
      if (this.beginPoint < this.endPoint) {
        Calendar start = copyCalendar(rc);
        Calendar end = copyCalendar(rc);
        end.add(Calendar.DAY_OF_MONTH, dayRange);
        return new Pair<>(start, end);
      }

      // in the past
      if (this.beginPoint > this.endPoint) {
        Calendar start = copyCalendar(rc);
        Calendar end = copyCalendar(rc);
        start.add(Calendar.DAY_OF_MONTH, 0 - dayRange);
        return new Pair<>(start, end);
      }

      throw new RuntimeException("begin and end are equal " + this);
    }

    // YYYYSP
    if (Pattern.matches("\\d+SP", this.val)) {
      int year = Integer.parseInt(this.val.substring(0, 4));
      Calendar start = makeCalendar(year, 2, 1);
      Calendar end = makeCalendar(year, 4, 31);
      return new Pair<>(start, end);
    }
    // YYYYSU
    if (Pattern.matches("\\d+SU", this.val)) {
      int year = Integer.parseInt(this.val.substring(0, 4));
      Calendar start = makeCalendar(year, 5, 1);
      Calendar end = makeCalendar(year, 7, 31);
      return new Pair<>(start, end);
    }
    // YYYYFA
    if (Pattern.matches("\\d+FA", this.val)) {

View on GitHub (pinned to 1b7edd19c4)