{"record":{"id":"74d48b1fc5ae08c4","repo":"stanfordnlp/CoreNLP","slug":"begin-and-end-are-equal-this","errorCode":null,"errorMessage":"begin and end are equal ${this}","messagePattern":"begin and end are equal (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/time/Timex.java","lineNumber":467,"sourceCode":"      int yearRange = Integer.parseInt(this.val.substring(1, this.val.length() - 1));\n\n      // in the future\n      if (this.beginPoint < this.endPoint) {\n        Calendar start = copyCalendar(rc);\n        Calendar end = copyCalendar(rc);\n        end.add(Calendar.YEAR, yearRange);\n        return new Pair<>(start, end);\n      }\n\n      // in the past\n      else if (this.beginPoint > this.endPoint) {\n        Calendar start = copyCalendar(rc);\n        Calendar end = copyCalendar(rc);\n        start.add(Calendar.YEAR, 0 - yearRange);\n        return new Pair<>(start, end);\n      }\n\n      throw new RuntimeException(\"begin and end are equal \" + this);\n    }\n    // PDDM\n    if (Pattern.matches(\"P\\\\d+M\", this.val) && documentTime != null) {\n      Calendar rc = documentTime.getDate();\n      int monthRange = Integer.parseInt(this.val.substring(1, this.val.length() - 1));\n\n      // in the future\n      if (this.beginPoint < this.endPoint) {\n        Calendar start = copyCalendar(rc);\n        Calendar end = copyCalendar(rc);\n        end.add(Calendar.MONTH, monthRange);\n        return new Pair<>(start, end);\n      }\n\n      // in the past\n      if (this.beginPoint > this.endPoint) {\n        Calendar start = copyCalendar(rc);\n        Calendar end = copyCalendar(rc);","sourceCodeStart":449,"sourceCodeEnd":485,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/time/Timex.java#L449-L485","documentation":"While expanding a duration of the form P##Y (years) relative to a document time, Timex.getRange computes start = docTime - N years and end = docTime; if the parsed yearRange is 0 it throws RuntimeException 'begin and end are equal'. A zero-width range is considered a bug/invalid input rather than a valid point.","triggerScenarios":"Calling getRange(documentTime) on a Timex whose val matches P\\\\d+Y with the digit part being 0 (e.g. 'P0Y').","commonSituations":"TimeML corpora containing degenerate durations like P0Y, often from upstream annotation or normalizer bugs that emitted a zero-length duration.","solutions":["Fix upstream annotation/normalization so P0Y durations are not produced","Treat P0Y as a point: use documentTime.getDate() instead of getRange()","Catch RuntimeException from getRange and substitute a zero-width range","Pre-validate: reject vals matching 'P0Y'"],"exampleFix":"// before\nPair<Calendar,Calendar> range = timex.getRange(documentTime);\n// after\nif (timex.val().matches(\"P0+Y\")) {\n  Calendar now = documentTime.getDate();\n  Pair<Calendar,Calendar> range = new Pair<>(now, now);\n} else {\n  Pair<Calendar,Calendar> range = timex.getRange(documentTime);\n}","handlingStrategy":"validation","validationCode":"if (timex.val() != null && timex.val().matches(\"P0+Y\")) { handleAsPoint(); }","typeGuard":null,"tryCatchPattern":"try { range = timex.getRange(docTime); } catch (RuntimeException e) { range = new Pair<>(docTime.getDate(), docTime.getDate()); }","preventionTips":["Sanitize durations with zero magnitude before range extraction","Add corpus QA checks for P0Y/P0M/P0D values","Catch RuntimeException around getRange in batch pipelines"],"tags":["java","timex","duration"],"backgroundTag":"invalid-argument-value","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}