{"record":{"id":"4a1fb9dc7be35fcf","repo":"stanfordnlp/CoreNLP","slug":"semgrex-pattern-asked-for-uniq-of-node-which-does","errorCode":null,"errorMessage":"Semgrex pattern asked for uniq of node  which does not exist in the pattern","messagePattern":"Semgrex pattern asked for uniq of node  which does not exist in the pattern","errorType":"validation","errorClass":"SemgrexParseException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/semgraph/semgrex/SemgrexParser.java","lineNumber":125,"sourceCode":"uniqKeys = new ArrayList<>();\n      label_2:\n      while (true) {\n        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {\n        case UNIQ:\n        case IDENTIFIER:{\n          ;\n          break;\n          }\n        default:\n          jj_la1[2] = jj_gen;\n          break label_2;\n        }\n        nextIdentifier = identifier();\nuniqKeys.add(nextIdentifier.image);\n      }\nfor (String key : uniqKeys) {\n          if (!knownVariables.contains(key)) {\n            {if (true) throw new SemgrexParseException(\"Semgrex pattern asked for uniq of node \" + key + \" which does not exist in the pattern\");}\n          }\n        }\n        // TODO: can error check that the keys are unique between node and edge names\n        // that might require keeping edge names in a known set\n        // TODO: edge names might need some upgrades anyway - shouldn't name them under negation, for example\n        node = new UniqPattern(node, uniqKeys);\n      break;\n      }\n    default:\n      jj_la1[3] = jj_gen;\n      ;\n    }\n    jj_consume_token(12);\n{if (\"\" != null) return node;}\n    throw new Error(\"Missing return statement in function\");\n}\n\n  final public SemgrexPattern SubNode(GraphRelation r) throws ParseException {SemgrexPattern result =  null;","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/semgraph/semgrex/SemgrexParser.java#L107-L143","documentation":"SemgrexParser validates the 'uniq' feature against the set of variables named elsewhere in the pattern. If a uniq key does not correspond to any named node in the pattern, Root() throws this SemgrexParseException because uniq can only reference nodes the pattern actually matched and named.","triggerScenarios":"Compiling a pattern with a uniq(...) clause listing an identifier that never appears as a named node in the pattern, e.g. 'UniqPattern' keys not present in knownVariables — such as '{}' > uniq(missingNode) where no node was named 'missingNode'.","commonSituations":"Typos in uniq key names after renaming nodes; refactoring a pattern and deleting a named node but leaving its uniq entry; hand-writing uniq keys without naming nodes with '='; patterns generated programmatically with stale key lists.","solutions":["Add the missing node name to the pattern with '=' (e.g. '=missingNode') so uniq has a valid target.","Correct the uniq key spelling to exactly match an existing named node in the pattern.","Remove the stale uniq entry if the node no longer exists in the pattern.","Note the related TODO in the source: keys must also be unique between node and edge names — avoid reusing identifiers across both."],"exampleFix":"// before\nSemgrexPattern.compile(\"{} > (nsubj) {} : uniq(ghost)\");\n// after\nSemgrexPattern.compile(\"{}=src > (nsubj) {} : uniq(src)\");","handlingStrategy":"validation","validationCode":"Set<String> names = new HashSet<>();\nMatcher m = Pattern.compile(\"=([A-Za-z_][\\\\w-]*)\").matcher(semgrex);\nwhile (m.find()) names.add(m.group(1));\nMatcher u = Pattern.compile(\"uniq\\\\(([^)]+)\\\\)\").matcher(semgrex);\nwhile (u.find()) if (!names.contains(u.group(1).trim())) throw new IllegalArgumentException(\"uniq key not in pattern: \" + u.group(1));","typeGuard":null,"tryCatchPattern":"try { SemgrexPattern.compile(semgrex); } catch (SemgrexParseException e) { throw new IllegalArgumentException(\"uniq references unknown node: \" + semgrex, e); }","preventionTips":["Name every node you intend to uniq with '=' and reuse the exact identifier","Grep rule files for uniq( keys and cross-check against =name tokens","Avoid reusing identifiers between node and edge names","Test each rule by compiling it in CI before deployment"],"tags":["java","parser","validation","semgrex"],"backgroundTag":"resource-not-found","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"}