{"record":{"id":"408e3af7f0e44996","repo":"stanfordnlp/CoreNLP","slug":"timex3-should-only-contain-text-child","errorCode":null,"errorMessage":"TIMEX3 should only contain text ${child}","messagePattern":"TIMEX3 should only contain text (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/time/GUTimeAnnotator.java","lineNumber":280,"sourceCode":"    for (int i = 0; i < docNodes.getLength(); i++) {\n      Node n = docNodes.item(i);\n      if (\"text\".equals(n.getNodeName())) {\n        textElem = (Element) n;\n        break;\n      }\n    }\n    NodeList textNodes = textElem.getChildNodes();\n    for (int i = 0; i < textNodes.getLength(); i++) {\n      Node content = textNodes.item(i);\n      if (content instanceof Text) {\n        Text text = (Text)content;\n        offset += text.getWholeText().length();\n      } else if (content instanceof Element) {\n        Element child = (Element)content;\n        if (child.getNodeName().equals(\"TIMEX3\")) {\n          Timex timex = new Timex(child);\n          if (child.getChildNodes().getLength() != 1) {\n            throw new RuntimeException(\"TIMEX3 should only contain text \" + child);\n          }\n          String timexText = child.getTextContent();\n          CoreMap timexMap = new ArrayCoreMap();\n          //(timex)\n          timexMap.set(TimeAnnotations.TimexAnnotation.class, timex);\n          //(text)\n          timexMap.set(CoreAnnotations.TextAnnotation.class, timexText);\n          //(characters)\n          int charBegin = offset;\n          timexMap.set(CoreAnnotations.CharacterOffsetBeginAnnotation.class, charBegin);\n          offset += timexText.length();\n          int charEnd = offset;\n          timexMap.set(CoreAnnotations.CharacterOffsetEndAnnotation.class, charEnd);\n          //(tokens)\n          if(haveTokenOffsets){\n            Integer tokBegin = beginMap.get(charBegin);\n            int searchStep = 1;          //if no exact match, search around the character offset\n            while(tokBegin == null){","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/time/GUTimeAnnotator.java#L262-L298","documentation":"When converting GUTime's XML output into CoreMaps, toTimexCoreMaps expects every TIMEX3 element to wrap exactly one child node (the text). If a TIMEX3 element contains zero or more than one child node (e.g. nested markup or split text nodes), the annotator throws this RuntimeException because it cannot represent it as a single text timex.","triggerScenarios":"GUTime emits TIMEX3 elements containing nested elements or multiple text nodes — typically due to unusual input markup, HTML fragments passed through to GUTime, or an unexpected GUTime version producing a different XML schema than expected.","commonSituations":"Annotating documents that already contain inline markup (XML/HTML) that survives into GUTime output; using a newer/older GUTime release whose TIMEX3 serialization differs from what the CoreNLP parser assumes.","solutions":["Log the offending TIMEX3 element (it is included in the message) and inspect what extra child nodes it contains","Strip/escape inline markup from the input text before annotation so GUTime emits plain-text TIMEX3 elements","Preprocess the GUTime XML output to merge/split non-conforming TIMEX3 elements before calling toTimexCoreMaps","Align the GUTime version with the one CoreNLP was built against"],"exampleFix":"// before\nString text = docHtml; // contains <b>Feb 3</b> inline markup\nguTimeAnnotator.annotate(new Annotation(text));\n// after\nString text = docHtml.replaceAll(\"<[^>]+>\", \"\"); // plain text only\nguTimeAnnotator.annotate(new Annotation(text));","handlingStrategy":"validation","validationCode":"// Validate TIMEX3 elements in GUTime output before conversion\nNodeList timexes = outputXML.getElementsByTagName(\"TIMEX3\");\nfor (int i = 0; i < timexes.getLength(); i++) {\n  Element e = (Element) timexes.item(i);\n  if (e.getChildNodes().getLength() != 1)\n    throw new IllegalStateException(\"Non-conforming TIMEX3 at index \" + i + \": \" + e.getTextContent());\n}","typeGuard":null,"tryCatchPattern":"try {\n  guTimeAnnotator.annotate(annotation);\n} catch (RuntimeException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"TIMEX3 should only contain text\")) {\n    logger.warning(\"Skipping malformed TIMEX3: \" + e.getMessage());\n  } else throw e;\n}","preventionTips":["Pass plain text (markup stripped) to the annotator so TIMEX3 elements contain a single text node","Pin a GUTime version compatible with CoreNLP's output parser","Log the full element from the message to spot systematic input issues"],"tags":["java","nlp","xml","parsing"],"backgroundTag":"unexpected-response-shape","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"}