{"record":{"id":"f7836689f30c7000","repo":"stanfordnlp/CoreNLP","slug":"between-when-the-internal-phrase-edge-was-found-an","errorCode":null,"errorMessage":"Between when the internal phrase edge was found and now, the edge was somehow deleted","messagePattern":"Between when the internal phrase edge was found and now, the edge was somehow deleted","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/SetPhraseHead.java","lineNumber":151,"sourceCode":"\n    for (SemanticGraphEdge edge : relocateEdges) {\n      SemanticGraphEdge newEdge = new SemanticGraphEdge(newHead,\n                                                        edge.getTarget(),\n                                                        edge.getRelation(),\n                                                        edge.getWeight(),\n                                                        edge.isExtra());\n      boolean success = sg.removeEdge(edge);\n      if (!success) {\n        throw new RuntimeException(\"Between when the incoming edge was found and now, the edge was somehow deleted\");\n      }\n      sg.addEdge(newEdge);\n      modified = true;\n    }\n\n    for (SemanticGraphEdge edge : deleteEdges) {\n      boolean success = sg.removeEdge(edge);\n      if (!success) {\n        throw new RuntimeException(\"Between when the internal phrase edge was found and now, the edge was somehow deleted\");\n      }\n      modified = true;\n    }\n    for (IndexedWord other : matchedNodes) {\n      if (other == newHead)\n        continue;\n\n      found: {\n        for (SemanticGraphEdge existingEdge : sg.getAllEdges(newHead, other)) {\n          if (existingEdge.getRelation().equals(relation)) {\n            break found;\n          }\n        }\n        SemanticGraphEdge newEdge = new SemanticGraphEdge(newHead,\n                                                          other,\n                                                          relation,\n                                                          weight,\n                                                          false);","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/SetPhraseHead.java#L133-L169","documentation":"SetPhraseHead.evaluate() deletes the internal edges of the extracted phrase (edges among matched nodes) via sg.removeEdge(edge). If removal fails because the edge is already gone, this RuntimeException is thrown — a defensive check that the graph did not change between edge collection and deletion.","triggerScenarios":"evaluate() invoked when internal phrase edges were already removed (e.g. the rule ran once before on the same graph, or an overlapping rule deleted them), making removeEdge return false.","commonSituations":"Running a ssurgeon pipeline where two rules match overlapping node sets; junit/test fixtures reusing one SemanticGraph across assertions; manually pre-pruning edges then invoking SetPhraseHead.","solutions":["Guard against double application: track which rules already ran or re-run semgrex matching before each evaluate","Ensure each matched phrase is edited exactly once per pipeline run","Restore the original graph between repeated evaluations (deep copy before edit)","Check prior ssurgeon operations in the pipeline for overlapping delete behavior"],"exampleFix":"// before\nssurgeon.apply(sg, rule); ssurgeon.apply(sg, rule);\n// after\nSemanticGraph copy = new SemanticGraph(sg);\nssurgeon.apply(copy, rule); // apply once per graph instance","handlingStrategy":"try-catch","validationCode":"// check internal phrase edges exist before delete loop\nfor (SemanticGraphEdge e : deleteEdges) {\n  if (sg.getEdge(e.getSource(), e.getTarget(), e.getRelation()) == null) { /* refresh matches */ }\n}","typeGuard":null,"tryCatchPattern":"try { op.evaluate(sg, sm); } catch (RuntimeException e) { if (e.getMessage().contains(\"internal phrase edge\")) { /* re-match on fresh copy and retry */ } else { throw e; } }","preventionTips":["Guard against applying the same rule twice to one graph","Use non-overlapping ssurgeon rules or re-match between rules","Deep-copy the graph before evaluation in tests"],"tags":["ssurgeon","semgraph","invariant"],"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-15T23:17:13.987Z"}