stanfordnlp/CoreNLP · error · RuntimeException

unexpected element

Error message

unexpected element ${child}

What it means

toTimexCoreMaps walks the children of GUTime's output XML root; Text nodes and TIMEX3 Elements are the only accepted content types. If a child is an Element whose node name is not TIMEX3 (e.g. some other tag GUTime emitted), a RuntimeException naming that element is thrown, since the parser has no rule for it.

Solutions

  1. Inspect the element named in the exception message to learn which tag GUTime emitted
  2. Use the GUTime version matching CoreNLP's expected output schema
  3. Pre-filter the GUTime XML: remove or unwrap unknown elements before parsing
  4. Sanitize input markup so only plain text reaches GUTime
  5. Patch toTimexCoreMaps to handle the extra tag type if it carries timex information

Example fix

// before
String text = htmlWithMarkup; // markup flows into GUTime output XML
new GUTimeAnnotator().annotate(annotation);
// after
String text = Jsoup.parse(htmlWithMarkup).text(); // strip markup first
new GUTimeAnnotator().annotate(new Annotation(text));
Defensive patterns

Strategy: validation

Validate before calling

// Check GUTime output contains only Text/TIMEX3 nodes before conversion
NodeList children = outputXML.getDocumentElement().getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
  org.w3c.dom.Node n = children.item(i);
  boolean ok = n.getNodeType() == org.w3c.dom.Node.TEXT_NODE
      || (n.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE && n.getNodeName().equals("TIMEX3"));
  if (!ok) throw new IllegalStateException("Unsupported GUTime output node: " + n.getNodeName());
}

Try / catch

try {
  guTimeAnnotator.annotate(annotation);
} catch (RuntimeException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("unexpected element")) {
    logger.warning("GUTime emitted unknown element: " + e.getMessage());
  } else throw e;
}

Prevention

When it happens

Trigger: GUTime output contains non-TIMEX3 element children inside the document body — caused by a GUTime version emitting a different tag set, or by markup in the input that GUTime passes through wrapped in another element.

Common situations: Version drift between the external GUTime tool and CoreNLP's GUTimeAnnotator expectations; annotated HTML input producing wrapper elements in output XML.

Related errors


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

Appendix: source

Thrown at src/edu/stanford/nlp/time/GUTimeAnnotator.java:320

              }
              searchStep += 1;
            }
            searchStep = 1;
            Integer tokEnd = endMap.get(charEnd);
            while(tokEnd == null){
              tokEnd = endMap.get(charEnd - searchStep);
              if(tokEnd == null){
                tokEnd = endMap.get(charEnd + searchStep);
              }
              searchStep += 1;
            }
            timexMap.set(CoreAnnotations.TokenBeginAnnotation.class, tokBegin);
            timexMap.set(CoreAnnotations.TokenEndAnnotation.class, tokEnd);
          }
          //(add)
          timexMaps.add(timexMap);
        } else {
          throw new RuntimeException("unexpected element " + child);
        }
      } else {
        throw new RuntimeException("unexpected content " + content);
      }
    }
    return timexMaps;
  }


  @Override
  public Set<Class<? extends CoreAnnotation>> requires() {
    return Collections.unmodifiableSet(new ArraySet<>(Arrays.asList(
        CoreAnnotations.TextAnnotation.class,
        CoreAnnotations.TokensAnnotation.class,
        CoreAnnotations.CharacterOffsetBeginAnnotation.class,
        CoreAnnotations.CharacterOffsetEndAnnotation.class,
        CoreAnnotations.SentencesAnnotation.class
    )));

View on GitHub (pinned to 1b7edd19c4)