stanfordnlp/CoreNLP · error · RuntimeException

minValue for feature

Error message

minValue for feature 

What it means

During scaleFeatures, every feature is expected to have been observed at least once so a minimum value can be recorded; minValues[f] is initialized to +Infinity. If a feature appears in featureIndex but never in any datum's values, the minimum stays Infinity and the method throws rather than scale with undefined bounds. The message reports which feature index lacked an assigned minimum.

Solutions

  1. Ensure every feature in the featureIndex occurs with at least one real value in the dataset before calling scaleFeatures (check with a scan over all datums)
  2. Call scaleFeatures once on the full dataset (letting it compute and cache min/max) instead of scaleDatum per-datum, so bounds are computed over all data
  3. Rebuild the dataset so the featureIndex contains only features actually observed in datums
  4. If a feature legitimately has no data, remove it from featureIndex or seed min/max handling with sensible defaults

Example fix

// before
ds.add(new RVFDatum<>(new ClassicCounter<String>(), "classA")); // empty datum, features missing
ds.scaleFeatures();
// after
classicCounts.remove("missingFeature"); // ensure features seen in datums exist
ds.add(new RVFDatum<>(classicCounts, "classA"));
ds.scaleFeatures(); // all features have assigned min/max
Defensive patterns

Strategy: validation

Validate before calling

Set<String> seen = new HashSet<>();
for (int i = 0; i < ds.size(); i++) for (ClassifiableFeature f : ds.get(i).asFeatures()) seen.add(featureName);
for (int f = 0; f < ds.featureIndex().size(); f++) {
  if (!seen.contains(ds.featureIndex().get(f))) throw new IllegalStateException("Feature " + f + " never observed; scaleFeatures will fail");
}

Try / catch

try {
  ds.scaleFeatures();
} catch (RuntimeException e) {
  if (e.getMessage().startsWith("minValue")) {
    logger.warning("Unobserved feature(s): rebuild dataset with observed features only");
  } else throw e;
}

Prevention

When it happens

Trigger: Calling scaleFeatures (directly or via scaleDatum, which calls it when min/max are not cached) on an RVFDataset where some features registered in the featureIndex never occur with a value in any datum, e.g. empty datums or a featureIndex built with locked/extra entries.

Common situations: Merging datasets where the featureIndex was locked before all features were added, datums added with only labels and no features, or a feature only ever appearing with default 0 values that never populate the values arrays used for min/max scanning.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at src/edu/stanford/nlp/classify/RVFDataset.java:197

    Arrays.fill(minValues, Double.POSITIVE_INFINITY);
    Arrays.fill(maxValues, Double.NEGATIVE_INFINITY);

    // first identify the max and min values for each feature.
    // System.out.printf("number of datums: %d dataset size: %d\n",data.length,size());
    for (int i = 0; i < size(); i++) {
      // System.out.printf("datum %d length %d\n", i,data[i].length);
      for (int j = 0; j < data[i].length; j++) {
        int f = data[i][j];
        if (values[i][j] < minValues[f])
          minValues[f] = values[i][j];
        if (values[i][j] > maxValues[f])
          maxValues[f] = values[i][j];
      }
    }

    for (int f = 0; f < featureIndex.size(); f++) {
      if (minValues[f] == Double.POSITIVE_INFINITY)
        throw new RuntimeException("minValue for feature " + f + " not assigned. ");
      if (maxValues[f] == Double.NEGATIVE_INFINITY)
        throw new RuntimeException("maxValue for feature " + f + " not assigned.");
    }

    // now scale each value such that it's between 0 and 1.
    for (int i = 0; i < size(); i++) {
      for (int j = 0; j < data[i].length; j++) {
        int f = data[i][j];
        if (minValues[f] != maxValues[f])// the equality can happen for binary
                                         // features which always take the value
                                         // of 1.0
          values[i][j] = (values[i][j] - minValues[f]) / (maxValues[f] - minValues[f]);
      }
    }

    /*
    for(int f = 0; f < featureIndex.size(); f++){
      if(minValues[f] == maxValues[f])

View on GitHub (pinned to 1b7edd19c4)