{"record":{"id":"f73d2058ca4a9200","repo":"stanfordnlp/CoreNLP","slug":"error-n-s-ninput-n-s-noutput-n-s","errorCode":null,"errorMessage":"error:\\n%s\\ninput:\\n%s\\noutput:\\n%s","messagePattern":"error:\\\\n(.+?)\\\\ninput:\\\\n(.+?)\\\\noutput:\\\\n(.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/time/GUTimeAnnotator.java","lineNumber":114,"sourceCode":"    output = docClose.matcher(output).replaceAll(\"</DOC>\");\n\n\n   //The TimeTag.pl result file contains next tags which must be removed\n    output = output.replaceAll(\"<lex.*?>\", \"\");\n    output = output.replace(\"</lex>\", \"\");\n    output = output.replace(\"<NG>\", \"\");\n    output = output.replace(\"</NG>\", \"\");\n    output = output.replace(\"<VG>\", \"\");\n    output = output.replace(\"</VG>\", \"\");\n    output = output.replace(\"<s>\", \"\");\n    output = output.replace(\"</s>\", \"\");\n\n    // parse the GUTime output\n    Element outputXML;\n    try {\n      outputXML = XMLUtils.parseElement(output);\n    } catch (Exception ex) {\n      throw new RuntimeException(String.format(\"error:\\n%s\\ninput:\\n%s\\noutput:\\n%s\",\n      \t\tex, IOUtils.slurpFile(inputFile), output), ex);\n    }\n    /*\n    try {\n      outputXML = new SAXBuilder().build(new StringReader(output)).getRootElement();\n    } catch (JDOMException e) {\n      throw new RuntimeException(String.format(\"error:\\n%s\\ninput:\\n%s\\noutput:\\n%s\",\n      \t\te, IOUtils.slurpFile(inputFile), output));\n    } */\n    inputFile.delete();\n\n    \n\n\n    // get Timex annotations\n    List<CoreMap> timexAnns = toTimexCoreMaps(outputXML, document);\n    document.set(TimeAnnotations.TimexAnnotations.class, timexAnns);\n    if (outputResults) {","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/time/GUTimeAnnotator.java#L96-L132","documentation":"GUTimeAnnotator runs an external GUTime perl process and parses its stdout as XML. XMLUtils.parseElement failed on that output, so the annotator wraps the parser exception together with the original input text and raw output in a RuntimeException. This means the GUTime binary produced output that is not well-formed XML, or the process failed entirely.","triggerScenarios":"Calling GUTimeAnnotator.annotate on an Annotation when (a) the bundled GUTime perl script/environment is broken (wrong perl version, missing perl modules, wrong gutime path), (b) GUTime crashes mid-processing and emits partial/garbage output, or (c) locale/encoding issues corrupt the XML (e.g. non-UTF8 bytes in the piped output).","commonSituations":"Deploying to a server without perl or without the modules GUTime needs (Perl4::CoreLibs etc.); macOS/Linux perl version differences; text containing characters that break GUTime's output encoding; running under a security sandbox that blocks the perl subprocess.","solutions":["Run the GUTime perl script manually on a small input file to reproduce and see the real underlying error in the wrapped exception (`ex`)","Verify perl and GUTime's required modules are installed and the script is executable (check `perl -v` and GUTime docs)","Print the captured `output` from the exception message and fix the input text that breaks it (control characters, invalid encoding)","Sanitize input: strip non-XML-safe characters (control chars, invalid UTF-8) before annotating","Consider switching to SUTime (pure-Java, bundled with CoreNLP) instead of the perl-based GUTime"],"exampleFix":"// before\nString raw = text; // may contain control chars that break GUTime output XML\npipeline.annotate(raw);\n// after\nString clean = text.replaceAll(\"\\\\p{Cntrl}\", \"\").getBytes(\"UTF-8\") != null ? new String(text.getBytes(\"UTF-8\"), \"UTF-8\") : text;\nAnnotation ann = new Annotation(clean);\npipeline.annotate(ann);","handlingStrategy":"try-catch","validationCode":"// Java: sanitize input before annotation\nString safe = text.replaceAll(\"\\\\p{Cntrl}\", \"\");\nbyte[] bytes = safe.getBytes(java.nio.charset.StandardCharsets.UTF_8);\nif (bytes.length == 0) throw new IllegalArgumentException(\"empty input for GUTime\");\n// also verify environment once at startup:\nProcess p = new ProcessBuilder(\"perl\", \"-v\").start();\nif (p.waitFor() != 0) throw new IllegalStateException(\"perl unavailable for GUTimeAnnotator\");","typeGuard":"boolean isGutimeReady(String text) {\n  return text != null && !text.trim().isEmpty()\n      && text.equals(new String(text.getBytes(java.nio.charset.StandardCharsets.UTF_8), java.nio.charset.StandardCharsets.UTF_8));\n}","tryCatchPattern":"try {\n  pipeline.annotate(annotation);\n} catch (RuntimeException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"error:\")) {\n    // log e.getCause() and the raw output embedded in the message; fall back to no time annotation\n    logger.warning(\"GUTime failed: \" + e.getCause());\n  } else throw e;\n}","preventionTips":["Prefer SUTime (pure Java) over GUTime to avoid the external perl dependency","Pin the perl version and required modules in your deployment (Docker image) and smoke-test GUTime at startup","Sanitize inputs: strip control characters and enforce UTF-8","Keep the exception's captured output for debugging — it contains GUTime's actual stdout"],"tags":["java","nlp","xml-parse","external-process"],"backgroundTag":"xml-parse-error","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"}