stanfordnlp/CoreNLP · error · RuntimeException
Could not find a valid edge to remove
Error message
Could not find a valid edge to remove
What it means
Util.cleanTree repeatedly deletes nodes from a dependency graph while keeping it a tree; for each removal it picks the best candidate edge to keep (toKeep) and verifies the removal via verifyRemoval. If no verified edge can be removed and there is no fallback (original == null), it throws RuntimeException "Could not find a valid edge to remove" — the graph cannot be reduced to a well-formed tree under the given constraints.
Solutions
- Verify the input graph passes isTree()/isDag() checks before calling cleanTree
- Inspect the graph for cycles or protected edges blocking all removals and fix the parse
- Provide/ensure the original edge fallback path so cleanTree can backtrack instead of throwing
Example fix
// before
Util.cleanTree(graph);
// after
if (!SemgraphicUtil.isTree(graph)) { /* fix or skip */ }
Util.cleanTree(graph); Defensive patterns
Strategy: validation
Validate before calling
if (!SemgraphicUtil.isTree(tree) || SemgraphicUtil.isCyclic(tree)) { /* repair or skip before cleanTree */ } Try / catch
try { Util.cleanTree(tree); } catch (RuntimeException e) { /* skip sentence or rebuild graph */ } Prevention
- Validate parse output is a tree before natural-logic preprocessing
- Avoid feeding enhanced/collapsed UD graphs directly into cleanTree
When it happens
Trigger: Calling Util.cleanTree on a SemanticGraph where every candidate removal fails verifyRemoval (e.g. edges whose relations are conj/subj/obj protected patterns) and no original edge is cached — typically an ill-formed or cyclic input graph that is not actually a tree.
Common situations: Feeding parser output containing cycles or re-entrancies into natural-login openie preprocessing; universal-Dependencies graphs with enhanced/collapsed edges; malformed conllu input.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- slurpFile IO problem
- slurpReader IO problem
- Error when parsing
- Failed to find node " + ie.source + "-" + ie.sourceCopy
- Failed to find node " + ie.target + "-" + ie.targetCopy
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/3de756827bae4a1c.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/naturalli/Util.java:278
// "\n Next edge found: " + candidate);
} else {
// either or both could be wrong, so we don't try to
// figure out which to keep
original = candidate;
}
}
if (toKeep == null) {
toKeep = candidate;
} else if (toKeep.getRelation().toString().startsWith("conj") && candidate.getRelation().toString().matches(".subj.*|.obj.*")) {
toKeep = candidate;
} else if (!candidate.isExtra() &&
!(candidate.getRelation().toString().startsWith("conj") && toKeep.getRelation().toString().matches(".subj.*|.obj.*"))) {
toKeep = candidate;
}
}
if (!verifyRemoval(tree, incomingEdges, toKeep, toKeep.getDependent())) {
if (original == null) {
throw new RuntimeException("Could not find a valid edge to remove");
}
toKeep = original;
}
List<SemanticGraphEdge> removeEdges = new ArrayList<>();
for (SemanticGraphEdge candidate : incomingEdges) {
if (candidate != toKeep) {
removeEdges.add(candidate);
}
}
removeEdges.forEach(tree::removeEdge);
extraEdges.addAll(removeEdges);
}
// Add apposition edges (simple coref)
for (SemanticGraphEdge extraEdge : new ArrayList<>(extraEdges)) { // note[gabor] prevent concurrent modification exception
for (SemanticGraphEdge candidateAppos : tree.incomingEdgeIterable(extraEdge.getDependent())) {
if (candidateAppos.getRelation().toString().equals("appos")) {
extraEdges.add(new SemanticGraphEdge(extraEdge.getGovernor(), candidateAppos.getGovernor(), extraEdge.getRelation(), extraEdge.getWeight(), extraEdge.isExtra()));View on GitHub (pinned to 1b7edd19c4)