{"record":{"id":"6d656eb155bcdf24","repo":"stanfordnlp/CoreNLP","slug":"unknown-position-in-adddep-position","errorCode":null,"errorMessage":"Unknown position in AddDep: |${position}|","messagePattern":"Unknown position in AddDep: \\|(.+?)\\|","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/AddDep.java","lineNumber":126,"sourceCode":"      tempIndex = SemanticGraphUtils.maxIndex(sg) + 2;\n\n      if (position.equals(\"-\")) {\n        newIndex = SemanticGraphUtils.minIndex(sg);\n      } else if (position.startsWith(\"-\") || position.startsWith(\"+\")) {\n        String targetName = position.substring(1);\n        IndexedWord target = sm.getNode(targetName);\n        if (target == null) {\n          return false;\n        }\n        if (position.startsWith(\"-\")) {\n          // it will be exactly to the left rather than pushing over\n          // something a word earlier if we do .index(), not .index() - 1\n          newIndex = target.index();\n        } else {\n          newIndex = target.index() + 1;\n        }\n      } else {\n        throw new UnsupportedOperationException(\"Unknown position in AddDep: |\" + position + \"|\");\n      }\n    } else {\n      tempIndex = SemanticGraphUtils.maxIndex(sg) + 1;\n      newIndex = -1;\n    }\n\n    newNode.setDocID(govNode.docID());\n    newNode.setIndex(tempIndex);\n    newNode.setSentIndex(govNode.sentIndex());\n\n    sg.addVertex(newNode);\n    sg.addEdge(govNode, newNode, relation, weight, false);\n\n    if (position != null && !position.equals(\"+\")) {\n      // the payoff for tempIndex == maxIndex + 2:\n      // everything will be moved one higher, unless it's the new node\n      SsurgeonUtils.moveNodes(sg, sm, x -> (x >= newIndex && x != tempIndex), x -> x+1, true);\n      SsurgeonUtils.moveNode(sg, sm, newNode, newIndex);","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/AddDep.java#L108-L144","documentation":"At evaluation time AddDep switches on the stored position string to compute the new node's index; if the position is a non-null value that was not one of the recognized signed-offset forms (or a legacy value the switch no longer handles), evaluate throws this UnsupportedOperationException. Unlike error 976, this fires at runtime during Ssurgeon execution, indicating a position format the constructor did not reject but evaluate cannot interpret.","triggerScenarios":"Executing an AddDep operation whose position string reaches the else-branch of the index computation in evaluate() — e.g. a position like \"0\", \" \", or a format accepted upstream but not matched by any case in the switch, on a graph where target.index() arithmetic cannot apply.","commonSituations":"Mixing Ssurgeon rule versions where position semantics changed; positions built programmatically as unsigned or descriptive strings; rules migrated between CoreNLP versions with different accepted position values.","solutions":["Change the position to a recognized signed form: negative (insert before target), positive (insert after target), or null for default end placement.","Re-check the Ssurgeon rule file: the exception prints the raw position between pipes (|value|), which usually reveals whitespace or an unexpected literal.","Update to a CoreNLP version whose AddDep constructor rejects the bad position up front (error 976) instead of failing at evaluate time.","Catch UnsupportedOperationException in the Ssurgeon driver and log the failing rule plus position for the rule author."],"exampleFix":"// before\nnew AddDep(\"gov\", rel, attrs, \"0\"); // parses, fails in evaluate()\n// after\nnew AddDep(\"gov\", rel, attrs, null); // default placement, or \"+1\"/\"-1\"","handlingStrategy":"try-catch","validationCode":"if (position != null && !(position.startsWith(\"-\") || position.startsWith(\"+\"))) position = null; // fall back to default placement","typeGuard":null,"tryCatchPattern":"try { addDep.evaluate(sg, match, env); } catch (UnsupportedOperationException e) { log.error(\"AddDep bad position: {}\", addDep); throw e; }","preventionTips":["Restrict positions to null or -N/+N strings","Log the raw |position| from the exception message to spot whitespace or literals in rule files","Upgrade CoreNLP so bad positions are rejected at construction time (SsurgeonParseException) instead of at evaluate time","Add a smoke test that evaluates every shipped Ssurgeon rule on a sample graph"],"tags":["java","ssurgeon","runtime","unsupported-operation"],"backgroundTag":"invalid-argument-value","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"}