stanfordnlp/CoreNLP · error · RuntimeException
Between when the internal phrase edge was found and now…
Error message
Between when the internal phrase edge was found and now, the edge was somehow deleted
What it means
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.
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
Example fix
// before ssurgeon.apply(sg, rule); ssurgeon.apply(sg, rule); // after SemanticGraph copy = new SemanticGraph(sg); ssurgeon.apply(copy, rule); // apply once per graph instance
Defensive patterns
Strategy: try-catch
Validate before calling
// check internal phrase edges exist before delete loop
for (SemanticGraphEdge e : deleteEdges) {
if (sg.getEdge(e.getSource(), e.getTarget(), e.getRelation()) == null) { /* refresh matches */ }
} Try / catch
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; } } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
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
- Between when the outgoing edge was found and now, the edge…
- Between when the incoming edge was found and now, the edge…
- oldTag starts with B, entity at position should not be null
- node cliqueFeatures[n]=
- edge cliqueFeatures[n]=
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/f7836689f30c7000.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/SetPhraseHead.java:151
for (SemanticGraphEdge edge : relocateEdges) {
SemanticGraphEdge newEdge = new SemanticGraphEdge(newHead,
edge.getTarget(),
edge.getRelation(),
edge.getWeight(),
edge.isExtra());
boolean success = sg.removeEdge(edge);
if (!success) {
throw new RuntimeException("Between when the incoming edge was found and now, the edge was somehow deleted");
}
sg.addEdge(newEdge);
modified = true;
}
for (SemanticGraphEdge edge : deleteEdges) {
boolean success = sg.removeEdge(edge);
if (!success) {
throw new RuntimeException("Between when the internal phrase edge was found and now, the edge was somehow deleted");
}
modified = true;
}
for (IndexedWord other : matchedNodes) {
if (other == newHead)
continue;
found: {
for (SemanticGraphEdge existingEdge : sg.getAllEdges(newHead, other)) {
if (existingEdge.getRelation().equals(relation)) {
break found;
}
}
SemanticGraphEdge newEdge = new SemanticGraphEdge(newHead,
other,
relation,
weight,
false);View on GitHub (pinned to 1b7edd19c4)