stanfordnlp/CoreNLP · error · RuntimeException

Unable to find sieve ordering to satisfy all ordering constr

Error message

Unable to find sieve ordering to satisfy all ordering constraints!!!!

What it means

When optimizing the sieve order, the system greedily builds a total order: at each position it computes the set of sieve indices allowed by the remaining ordering constraints (selectableSieveIndices) and picks one. If this set becomes empty before all sieves are placed, the constraints are unsatisfiable and a RuntimeException 'Unable to find sieve ordering to satisfy all ordering constraints!!!!' is thrown.

Solutions

  1. Check the ordering constraints for cycles (e.g. A<B, B<C, C<A) and remove/reverse one to break the loop
  2. Reduce the constraint set to a minimal consistent subset and re-run to isolate the conflict
  3. Draw the constraints as a directed graph and verify it is a DAG before configuring
  4. Use fewer or looser constraints (replace explicit pairs with the allowed single '*<' and '<*' wildcards)

Example fix

// before
dcoref.optimize.sievesOrder = A<B, B<C, C<A   // cycle: unsatisfiable
// after
dcoref.optimize.sievesOrder = A<B, B<C
Defensive patterns

Strategy: validation

Validate before calling

// verify constraints are acyclic before running
Map<String,List<String>> g = new HashMap<>();
for (String o : props.getProperty("dcoref.optimize.sievesOrder","").split(",")) {
  String[] s = o.split("<");
  if (s.length==2 && !s[0].trim().equals("*") && !s[1].trim().equals("*"))
    g.computeIfAbsent(s[0].trim(), k->new ArrayList<>()).add(s[1].trim());
}
// topological sort; failure => cycle => would throw at runtime

Try / catch

try {
  SieveCoreferenceSystem coref = new SieveCoreferenceSystem(props);
  coref.runCoref(docReader);
} catch (RuntimeException e) {
  if (e.getMessage() != null && e.getMessage().contains("Unable to find sieve ordering")) {
    logger.severe("Constraints unsatisfiable (likely a cycle). Reducing constraint set.");
    props.setProperty("dcoref.optimize.sievesOrder", minimalConstraints);
  } else throw e;
}

Prevention

When it happens

Trigger: Configuring an ordering-constraints set that forms a cycle or otherwise admits no valid total order — e.g. A<B, B<C, C<A — so that after placing some sieves no remaining sieve satisfies all keepOrder constraints.

Common situations: Adding many pairwise constraints over time that silently introduce a cycle; combining one ANY-first and one ANY-second constraint with contradictory pairwise constraints; generated constraints from an automated tuner with a logic bug.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

Thrown at src/edu/stanford/nlp/dcoref/SieveCoreferenceSystem.java:688

              break;
            }
          } else if (ko.first() < 0 && remainingSieveIndices.size() > 1) {
            if (remainingSieveIndices.contains(ko.second())) {
              logger.info("Remove selection " + origSieveNames[ko.second()] + " because of constraint " +
                    toSieveOrderConstraintString(ko, origSieveNames));
              selectableSieveIndices.remove(ko.second());
            }
          } else if (remainingSieveIndices.contains(ko.first())) {
            if (remainingSieveIndices.contains(ko.second())) {
              logger.info("Remove selection " + origSieveNames[ko.second()] + " because of constraint " +
                    toSieveOrderConstraintString(ko, origSieveNames));
              selectableSieveIndices.remove(ko.second());
            }
          }
        }
      }
      if (selectableSieveIndices.isEmpty()) {
        throw new RuntimeException("Unable to find sieve ordering to satisfy all ordering constraints!!!!");
      }

      int selected = -1;
      if (selectableSieveIndices.size() > 1) {
        // Go through remaining sieves and see how well they do
        List<Pair<Double,Integer>> scores = new ArrayList<>();
        if (runDistributedCmd != null) {
          String workDirPath = mainWorkDirPath + curSievesNumber + File.separator;
          File workDir = new File(workDirPath);
          workDir.mkdirs();
          workDirPath = workDir.getAbsolutePath() + File.separator;
          // Start jobs
          for (int potentialSieveIndex:selectableSieveIndices) {
            String sieveSelectionId = curSievesNumber + "." + potentialSieveIndex;
            String jobDirPath = workDirPath + sieveSelectionId + File.separator;
            File jobDir = new File(jobDirPath);
            jobDir.mkdirs();
            Properties newProps = new Properties();

View on GitHub (pinned to 1b7edd19c4)