stanfordnlp/CoreNLP · error · RuntimeException

error:\n \ninput:\n

Error message

error:\n%s\ninput:\n%s

What it means

toAnnotation parses the assembled gigaword XML with XOM's Builder. If the XML is malformed (ParsingException) or reading fails (IOException), the method throws a RuntimeException containing the parser error and the full offending XML input, so the developer can see exactly what failed to parse.

Solutions

  1. Read the parser error in the exception message to find the malformed position, then fix the source document or pre-escape entities.
  2. Escape XML special characters (&, <, >) in the text content before building the string (e.g. with StringEscapeUtils.escapeXml10).
  3. Fix the pre-processing regexes (sid quoting, </TEXT> insertion) so they generate well-formed XML for edge-case documents.

Example fix

// before
xml = new String(xml.getBytes(), "UTF8");
return toAnnotation(xml);
// after
xml = xml.replaceAll("&(?!(amp|lt|gt|quot|apos|#\\d+|#x[0-9a-fA-F]+);)", "&amp;");
xml = new String(xml.getBytes(), "UTF8");
return toAnnotation(xml);
Defensive patterns

Strategy: try-catch

Validate before calling

// sanity-check XML well-formedness before toAnnotation
if (!xml.startsWith("<DOC") || xml.contains("<&") || countUnescapedAmpersands(xml) > 0) {
  logger.warning("Suspicious XML for document: " + xml.substring(0, 200));
}

Try / catch

try {
  CoreMap doc = ParsedGigawordReader.toAnnotation(xml);
} catch (RuntimeException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("error:")) {
    logger.warning("Unparseable XML, skipping: " + e.getMessage().substring(0, 300));
    return null; // skip document
  }
  throw e;
}

Prevention

When it happens

Trigger: The regex rewrites (adding quotes around sid, inserting </TEXT>) producing invalid XML — unescaped '&', '<' in the text, attributes not properly quoted, or nested markup that violates XML well-formedness.

Common situations: Gigaword sentences containing raw '&' or '<' characters that were never XML-escaped; sid attributes with characters breaking the naive sid regex fix; documents missing expected SENT/TEXT structure.

Understand the failure class

Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at src/edu/stanford/nlp/time/ParsedGigawordReader.java:188

    matcher.find();
    Calendar docDate = new Timex(matcher.group(1)).getDate();

    Annotation document = new Annotation(text.toString());
    document.set(CoreAnnotations.DocIDAnnotation.class, docID);
    document.set(CoreAnnotations.CalendarAnnotation.class, docDate);
    document.set(CoreAnnotations.SentencesAnnotation.class, sentences);
    return document;
  }
  */

  private static Annotation toAnnotation(String xml) throws IOException {
    Element docElem;
    try {
      Builder parser = new Builder();
      StringReader in = new StringReader(xml);
      docElem = parser.build(in).getRootElement();
    } catch (ParsingException | IOException e) {
      throw new RuntimeException(String.format("error:\n%s\ninput:\n%s", e, xml));
    }

    Element textElem = docElem.getFirstChildElement("TEXT");
    StringBuilder text = new StringBuilder();
    int offset = 0;
    List<CoreMap> sentences = new ArrayList<>();
    Elements sentenceElements = textElem.getChildElements("SENT");
    for (int crtsent = 0; crtsent < sentenceElements.size(); crtsent ++){
      Element sentElem = sentenceElements.get(crtsent);
      CoreMap sentence = new ArrayCoreMap();
      sentence.set(CoreAnnotations.CharacterOffsetBeginAnnotation.class, offset);
      Tree tree = Tree.valueOf(sentElem.getChild(0).getValue()); // XXX ms: is this the same as sentElem.getText() in JDOM?
      List<CoreLabel> tokens = new ArrayList<>();
      List<Tree> preTerminals = preTerminals(tree);
      for (Tree preTerminal: preTerminals) {
        String posTag = preTerminal.value();
        for (Tree wordTree: preTerminal.children()) {
          String word = wordTree.value();

View on GitHub (pinned to 1b7edd19c4)