{"record":{"id":"12e67ad6f183bb67","repo":"stanfordnlp/CoreNLP","slug":"found-an-edge-and-tried-to-delete-it-but-somehow","errorCode":null,"errorMessage":"Found an edge and tried to delete it, but somehow this didn't work!  ${edge}","messagePattern":"Found an edge and tried to delete it, but somehow this didn't work!  (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/RemoveEdge.java","lineNumber":76,"sourceCode":"   * same graph.\n   */\n  @Override\n  public boolean evaluate(SemanticGraph sg, SemgrexMatcher sm) {\n    boolean govWild = govName.equals(WILDCARD_NODE);\n    boolean depWild = depName.equals(WILDCARD_NODE);\n    IndexedWord govNode = getNamedNode(govName, sm);\n    IndexedWord depNode = getNamedNode(depName, sm);\n    boolean success = false;\n\n    List<SemanticGraphEdge> edgesToDelete = null;\n    if (govNode != null && depNode != null) {\n      if (relation == null) {\n        edgesToDelete = new ArrayList<>(sg.getAllEdges(govNode, depNode));\n      } else {\n        SemanticGraphEdge edge = sg.getEdge(govNode, depNode, relation);\n        while (edge != null) {\n          if (!sg.removeEdge(edge)) {\n            throw new IllegalStateException(\"Found an edge and tried to delete it, but somehow this didn't work!  \" + edge);\n          }\n          edge = sg.getEdge(govNode, depNode, relation);\n          success = true;\n        }\n      }\n    } else if (depNode != null && govWild) {\n      // dep known, wildcard gov\n      if (relation == null) {\n        edgesToDelete = new ArrayList<>();\n        sg.incomingEdgeIterable(depNode).forEach(edgesToDelete::add);\n      } else {\n        edgesToDelete = new ArrayList<>();\n        for (SemanticGraphEdge edge : sg.incomingEdgeIterable(depNode)) {\n          if (edge.getRelation().equals(relation)) {\n            edgesToDelete.add(edge);\n          }\n        }\n      }","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/RemoveEdge.java#L58-L94","documentation":"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.","triggerScenarios":"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.","commonSituations":"Sharing one SemanticGraph across threads while running Ssurgeon operations; a custom SemanticGraph subclass whose removeEdge behaves differently; the graph mutated between lookup and removal.","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"],"exampleFix":"// before\n// same SemanticGraph shared by multiple threads running ssurgeon.apply(graph)\n// after\nsynchronized (graph) { ssurgeon.apply(graph); }","handlingStrategy":"try-catch","validationCode":"// before running Ssurgeon, ensure exclusive access\nassert !graphBeingEditedConcurrently : \"SemanticGraph must be single-thread owned during Ssurgeon\";","typeGuard":null,"tryCatchPattern":"try {\n  ssurgeon.apply(graph, match);\n} catch (IllegalStateException e) {\n  if (e.getMessage().startsWith(\"Found an edge and tried to delete it\")) {\n    log.warn(\"Graph in inconsistent state; rebuilding graph and retrying once\");\n    graph = rebuildGraph(originalTree);\n    ssurgeon.apply(graph, match);\n  } else { throw e; }\n}","preventionTips":["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"],"tags":["java","ssurgeon","illegal-state"],"backgroundTag":"internal-invariant-violation","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}