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

  1. Ensure the SemanticGraph is not mutated concurrently while Ssurgeon operations run (synchronize or use one graph per thread)
  2. Re-run the operation on a freshly rebuilt SemanticGraph; a stale/corrupted graph usually resolves it
  3. Check for custom subclasses or wrappers of SemanticGraph overriding removeEdge/getEdge inconsistently
  4. 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

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


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)