{"record":{"id":"b21a9bb36071e9e6","repo":"stanfordnlp/CoreNLP","slug":"error-no-such-thing-as-zeroth-leaf","errorCode":null,"errorMessage":"Error -- no such thing as zeroth leaf!","messagePattern":"Error -- no such thing as zeroth leaf!","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/trees/tregex/Relation.java","lineNumber":1009,"sourceCode":"          }\n        }\n      };\n    }\n  };\n\n  /**\n   * Looks for the ith leaf of the current node\n   */\n  private static class AncestorOfIthLeaf extends Relation {\n\n    private static final long serialVersionUID = -6495191354526L;\n\n    private final int leafNum;\n\n    AncestorOfIthLeaf(int i) {\n      super(\"<<<\" + String.valueOf(i));\n      if (i == 0) {\n        throw new IllegalArgumentException(\"Error -- no such thing as zeroth leaf!\");\n      }\n      leafNum = i;\n    }\n\n    @Override\n    Iterator<Tree> searchNodeIterator(final Tree t,\n                                      final TregexMatcher matcher) {\n      return new SearchNodeIterator() {\n        @Override\n        void initialize() {\n          // this is a little lazy in terms of coding\n          // would be a bit faster to actually recurse through the tree\n          // this is unlikely to ever be a performance limitation, though\n          List<Tree> leaves = t.getLeaves();\n          if (leaves.size() >= Math.abs(leafNum)) {\n            final int index;\n            if (leafNum > 0) {\n              index = leafNum - 1;","sourceCodeStart":991,"sourceCodeEnd":1027,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/trees/tregex/Relation.java#L991-L1027","documentation":"Tregex's AncestorOfIthLeaf relation (<<i) matches the ancestor of the i-th leaf of a tree, using 1-based indexing. Constructing it with i == 0 is meaningless (there is no zeroth leaf), so the constructor throws IllegalArgumentException to fail fast during relation construction.","triggerScenarios":"A tregex pattern contains the relation '<<0' (e.g. \"A<<0\"), causing the parser to construct AncestorOfIthLeaf(0), which throws.","commonSituations":"Users writing patterns by hand or generating them programmatically with 0-based loop counters forget that tregex leaf/child indices are 1-based; a loop starting at i=0 emits <<0.","solutions":["Use 1-based indices: change <<0 to <<1 for the first leaf","Clamp or start programmatic index generation at 1","Catch IllegalArgumentException from TregexPattern.compile and report the offending pattern to the user"],"exampleFix":"// before\nString pattern = \"NP <<\" + i; // i starts at 0\n// after\nString pattern = \"NP <<\" + (i + 1); // 1-based leaf index","handlingStrategy":"validation","validationCode":"if (i < 1) throw new IllegalArgumentException(\"leaf index must be >= 1, got \" + i);\nTregexPattern.compile(pattern); // then catch IllegalArgumentException","typeGuard":"boolean validLeafIndex(int i) { return i >= 1; }","tryCatchPattern":"try { TregexPattern.compile(pattern); } catch (IllegalArgumentException e) { /* report bad <<i index */ }","preventionTips":["Remember tregex <<i and >i indices are 1-based","Start generated index loops at 1, not 0","Unit-test generated patterns with compile() before use"],"tags":["tregex","pattern-parsing","indexing"],"backgroundTag":"value-out-of-range","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"}