{"record":{"id":"253feb8e47e407a1","repo":"stanfordnlp/CoreNLP","slug":"child-should-only-be-set-on-a-uniqpattern-at-creat","errorCode":null,"errorMessage":"Child should only be set on a UniqPattern at creation time","messagePattern":"Child should only be set on a UniqPattern at creation time","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/semgraph/semgrex/UniqPattern.java","lineNumber":87,"sourceCode":"\n  @Override\n  public String localString() {\n    return toString(true, false);\n  }\n\n  @Override\n  public String toString() {\n    return toString(true, true);\n  }\n\n  @Override\n  public String toString(boolean hasPrecedence) {\n    return toString(hasPrecedence, true);\n  }\n\n  @Override\n  public void setChild(SemgrexPattern n) {\n    throw new UnsupportedOperationException(\"Child should only be set on a UniqPattern at creation time\");\n  }\n\n  @Override\n  public List<SemgrexPattern> getChildren() {\n    if (child == null) {\n      return Collections.emptyList();\n    } else {\n      return Collections.singletonList(child);\n    }\n  }\n\n  public String toString(boolean hasPrecedence, boolean addChild) {\n    StringBuilder sb = new StringBuilder();\n    if (addChild) {\n      sb.append(child.toString(true));\n    }\n    sb.append(\" :: uniq\");\n    for (String key : keys) {","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/semgraph/semgrex/UniqPattern.java#L69-L105","documentation":"UniqPattern overrides setChild to be unsupported: its single child is fixed at construction time, so any later attempt to attach or rewire a child throws this UnsupportedOperationException. It protects the invariant that a UniqPattern's child (the node whose matches must be unique) never changes after creation.","triggerScenarios":"Calling setChild(...) on a UniqPattern instance — typically via generic pattern-rewriting code, traversal utilities, or SemgrexParser paths that call the abstract setChild on all node patterns without special-casing UniqPattern.","commonSituations":"Custom Semgrex tooling that mutates pattern trees after compilation; serialization/deserialization or transformation frameworks that blindly call setChild on every node type; writing a parser extension that builds UniqPattern first and attaches its child later.","solutions":["Pass the child to the UniqPattern constructor instead of calling setChild afterwards.","Special-case UniqPattern in any generic tree-rewriting code and skip (or rebuild) it rather than calling setChild.","Rebuild the UniqPattern with the new child if the child must change — replace the node in the parent tree.","If you control the traversal, check instanceof UniqPattern before invoking setChild on pattern nodes."],"exampleFix":"// before\nUniqPattern up = new UniqPattern(node, keys);\nup.setChild(newChild); // UnsupportedOperationException\n// after\nUniqPattern up = new UniqPattern(newChild, keys); // child at construction time","handlingStrategy":"type-guard","validationCode":"if (pattern instanceof UniqPattern) { /* rebuild with new child instead of setChild */ }","typeGuard":"boolean isUniq = (p instanceof UniqPattern);\nif (isUniq) { UniqPattern up = (UniqPattern) p; /* treat as immutable */ }","tryCatchPattern":"try { node.setChild(newChild); } catch (UnsupportedOperationException e) { /* rebuild UniqPattern with the child in its constructor */ }","preventionTips":["Treat UniqPattern as immutable — set the child via the constructor","Special-case UniqPattern in generic tree rewriters before calling setChild","Replace-and-rebuild nodes rather than mutating them"],"tags":["java","unsupported-operation","semgrex","immutable"],"backgroundTag":"unsupported-operation","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"}