stanfordnlp/CoreNLP · error · java.lang.RuntimeException

Error loading units from " + options.unitsFilename

Error message

Error loading units from " + options.unitsFilename

What it means

QuantifiableEntityExtractor.initEnv calls Units.registerUnits(env, options.unitsFilename); an IOException while reading that file is wrapped in a RuntimeException naming the units file. The QE annotator cannot be initialized without its units definitions, so it fails fast during init.

Solutions

  1. Verify options.unitsFilename resolves from the process working directory; use an absolute path or classpath-resolvable resource.
  2. Check the file exists and is readable by the process user.
  3. Ship the units file inside the deployment/jar and load it via the classpath.
  4. Look at the wrapped IOException cause for the exact read/parse failure.

Example fix

// before
props.setProperty("qe.unitsFile", "units.txt");
// after: absolute or classpath-verified path
props.setProperty("qe.unitsFile", "/opt/models/qe/units.txt");
Defensive patterns

Strategy: validation

Validate before calling

File units = new File(options.unitsFilename);
if (!units.isFile() || !units.canRead())
  throw new IllegalArgumentException("Units file missing/unreadable: " + options.unitsFilename);

Try / catch

try {
  extractor.init(props);
} catch (RuntimeException e) {
  if (e.getMessage().startsWith("Error loading units from")) {
    log.severe("Fix qe units path: " + e.getCause());
  }
  throw e;
}

Prevention

When it happens

Trigger: Initializing the QE extractor with options.unitsFilename pointing to a missing, unreadable, or malformed units file (Units.registerUnits throws IOException on parse/read problems).

Common situations: Wrong path to the QE units file (often relative to a working directory that differs at runtime), missing resource when running from a jar, or a typo in the units file option.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at src/edu/stanford/nlp/ie/qe/QuantifiableEntityExtractor.java:72

    extractor = createExtractor();
  }

  private CoreMapExpressionExtractor<MatchedExpression> createExtractor() {
    List<String> filenames = StringUtils.split(options.grammarFilename, "\\s*[,;]\\s*");
    return CoreMapExpressionExtractor.createExtractorFromFiles(env, filenames);
  }

  private void initEnv() {
    env = TokenSequencePattern.getNewEnv();
    env.setDefaultTokensAnnotationKey(CoreAnnotations.NumerizedTokensAnnotation.class);

    // Do case insensitive matching
    env.setDefaultStringMatchFlags(Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
    env.setDefaultStringPatternFlags(Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
    try {
      Units.registerUnits(env, options.unitsFilename);
    } catch (IOException ex)  {
      throw new RuntimeException("Error loading units from " + options.unitsFilename, ex);
    }
    try {
      UnitPrefix.registerPrefixes(env, options.prefixFilename);
    } catch (IOException ex)  {
      throw new RuntimeException("Error loading prefixes from " + options.prefixFilename, ex);
    }
    env.bind("options", options);

    env.bind("numcomptype", CoreAnnotations.NumericCompositeTypeAnnotation.class);
    env.bind("numcompvalue", CoreAnnotations.NumericCompositeValueAnnotation.class);
  }

  private static void generatePrefixDefs(String infile, String outfile) throws IOException {
    List<UnitPrefix> prefixes = UnitPrefix.loadPrefixes(infile);
    PrintWriter pw = IOUtils.getPrintWriter(outfile);
    pw.println("SI_PREFIX_MAP = {");
    List<String> items = new ArrayList<>();
    for (UnitPrefix prefix : prefixes) {

View on GitHub (pinned to 1b7edd19c4)