stanfordnlp/CoreNLP · error · IllegalStateException
Found an edge and tried to delete it, but somehow this…
Error message
Found an edge and tried to delete it, but somehow this didn't work! ${edge} What it means
During RemoveEdge.evaluate, when a specific relation was given, the code looks up the exact edge between gov and dep and calls SemanticGraph.removeEdge. If removeEdge returns false despite the edge being found, the graph is in an inconsistent state relative to the lookup, and this IllegalStateException signals an internal invariant violation.
Solutions
- Ensure the SemanticGraph is not mutated concurrently while Ssurgeon operations run (synchronize or use one graph per thread)
- Re-run the operation on a freshly rebuilt SemanticGraph; a stale/corrupted graph usually resolves it
- Check for custom subclasses or wrappers of SemanticGraph overriding removeEdge/getEdge inconsistently
- Report upstream if reproducible on a single-threaded stock SemanticGraph, as this indicates a core bug
Example fix
// before
// same SemanticGraph shared by multiple threads running ssurgeon.apply(graph)
// after
synchronized (graph) { ssurgeon.apply(graph); } Defensive patterns
Strategy: try-catch
Validate before calling
// before running Ssurgeon, ensure exclusive access assert !graphBeingEditedConcurrently : "SemanticGraph must be single-thread owned during Ssurgeon";
Try / catch
try {
ssurgeon.apply(graph, match);
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("Found an edge and tried to delete it")) {
log.warn("Graph in inconsistent state; rebuilding graph and retrying once");
graph = rebuildGraph(originalTree);
ssurgeon.apply(graph, match);
} else { throw e; }
} Prevention
- Never share a mutable SemanticGraph across threads during Ssurgeon edits
- Apply each remove-edge operation once and re-match afterwards rather than mutating in loops
- Keep SemanticGraph instances owned by the same object that runs the Ssurgeon pipeline
When it happens
Trigger: Evaluating a remove-edge Ssurgeon operation on a SemanticGraph where getEdge(gov, dep, relation) returns an edge but removeEdge(edge) fails — typically concurrent modification of the graph, or an edge not actually attached to this graph instance.
Common situations: Sharing one SemanticGraph across threads while running Ssurgeon operations; a custom SemanticGraph subclass whose removeEdge behaves differently; the graph mutated between lookup and removal.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Bad WordShapeClassifier
- Call next() before calling remove()!
- Cannot combine MWT out of only
- Cannot make a KillAllIncomingEdges out of " +…
- Cannot make a Lemmatize with no nodeName
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/12e67ad6f183bb67.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/RemoveEdge.java:76
* same graph.
*/
@Override
public boolean evaluate(SemanticGraph sg, SemgrexMatcher sm) {
boolean govWild = govName.equals(WILDCARD_NODE);
boolean depWild = depName.equals(WILDCARD_NODE);
IndexedWord govNode = getNamedNode(govName, sm);
IndexedWord depNode = getNamedNode(depName, sm);
boolean success = false;
List<SemanticGraphEdge> edgesToDelete = null;
if (govNode != null && depNode != null) {
if (relation == null) {
edgesToDelete = new ArrayList<>(sg.getAllEdges(govNode, depNode));
} else {
SemanticGraphEdge edge = sg.getEdge(govNode, depNode, relation);
while (edge != null) {
if (!sg.removeEdge(edge)) {
throw new IllegalStateException("Found an edge and tried to delete it, but somehow this didn't work! " + edge);
}
edge = sg.getEdge(govNode, depNode, relation);
success = true;
}
}
} else if (depNode != null && govWild) {
// dep known, wildcard gov
if (relation == null) {
edgesToDelete = new ArrayList<>();
sg.incomingEdgeIterable(depNode).forEach(edgesToDelete::add);
} else {
edgesToDelete = new ArrayList<>();
for (SemanticGraphEdge edge : sg.incomingEdgeIterable(depNode)) {
if (edge.getRelation().equals(relation)) {
edgesToDelete.add(edge);
}
}
}View on GitHub (pinned to 1b7edd19c4)