{"record":{"id":"6a9fa1c068c7442f","repo":"stanfordnlp/CoreNLP","slug":"expected-corelabel-s-to-have-text","errorCode":null,"errorMessage":"Expected CoreLabel's to have text","messagePattern":"Expected CoreLabel's to have text","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/trees/Tree.java","lineNumber":1021,"sourceCode":"    StringWriter sw = new StringWriter();\n    pennPrint(new PrintWriter(sw));\n    return sw.toString();\n  }\n\n  /**\n   * Return String of leaves spanned by this tree assuming they are CoreLabel's\n   * Throws an IllegalArgumentException if the leaves are not CoreLabels that contain\n   * text info as in the typical use case of a Tree generated by a pipeline\n   *\n   * @return The text of the span of this Tree\n   */\n  public String spanString() {\n    // check this Tree supports this method by having properly populated CoreLabel's\n    List<Tree> leaves = this.getLeaves();\n    if (!(leaves.get(0).label() instanceof CoreLabel)) {\n      throw new IllegalArgumentException(\"Expected leaves to be CoreLabels\");\n    } else if (((CoreLabel) leaves.get(0).label()).word() == null) {\n      throw new IllegalArgumentException(\"Expected CoreLabel's to have text\");\n    } else if (((CoreLabel) leaves.get(0).label()).after() == null) {\n      throw new IllegalArgumentException(\"Expected CoreLabel's to have after() text\");\n    }\n    List<CoreLabel> coreLabels = this.getLeaves().stream().map(l -> ((CoreLabel) l.label())).collect(Collectors.toList());\n    // reconstruct original String from CoreLabel fields\n    String spanString = coreLabels.subList(0, Math.max(0, coreLabels.size()-1)).stream().map(\n            cl -> cl.word()+cl.after()).collect(Collectors.joining(\"\"));\n    // don't add the after of the last word\n    spanString += coreLabels.get(coreLabels.size()-1).word();\n    return spanString;\n  }\n\n\n  /**\n   * Print the tree as done in Penn Treebank merged files.\n   * The formatting should be exactly the same, but we don't print the\n   * trailing whitespace found in Penn Treebank trees.\n   * The tree is printed to {@code System.out}. The basic deviation","sourceCodeStart":1003,"sourceCodeEnd":1039,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/trees/Tree.java#L1003-L1039","documentation":"spanString() needs each leaf's CoreLabel.word() to hold the token text; without it the surface form cannot be reconstructed. When the first leaf is a CoreLabel but its word field is null, the library throws this IllegalArgumentException.","triggerScenarios":"Calling spanString() on a tree whose leaves are CoreLabels that were constructed without setting the word (e.g. only tag/value set, or labels created by factories that never populate WordAnnotation).","commonSituations":"Programmatically built trees where CoreLabels were created empty and only value() was set; tokenization done outside CoreNLP so WordAnnotation was never applied; trees whose leaves carry only part-of-speech info.","solutions":["Set the word on each leaf: ((CoreLabel) leaf.label()).setWord(tokenText) before calling spanString()","Run trees through LexedTokenFactory/tokenization that populates WordAnnotation, or re-tokenize with CoreNLP tokenize step","Use setWord/setValue consistently when constructing CoreLabels manually"],"exampleFix":"// before\nCoreLabel cl = new CoreLabel(); cl.setTag(\"NN\");\nleaf.setLabel(cl); tree.spanString(); // throws\n// after\ncl.setWord(\"dog\"); leaf.setLabel(cl); tree.spanString();","handlingStrategy":"type-guard","validationCode":"CoreLabel first = (CoreLabel) tree.getLeaves().get(0).label(); if (first.word() == null) throw new IllegalStateException(\"leaf CoreLabels missing word\");","typeGuard":"boolean leavesHaveWords(Tree t) { return t.getLeaves().stream().allMatch(l -> l.label() instanceof CoreLabel && ((CoreLabel) l.label()).word() != null); }","tryCatchPattern":"try { return tree.spanString(); } catch (IllegalArgumentException e) { leaves.forEach(l -> ((CoreLabel) l.label()).setWord(l.value())); return tree.spanString(); }","preventionTips":["Always setWord() when constructing leaf CoreLabels manually","Tokenize with CoreNLP tokenizers that populate WordAnnotation","Unit-test tree construction with a spanString() smoke check"],"tags":["validation","nlp","corelabel"],"backgroundTag":"empty-required-field","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"}