stanfordnlp/CoreNLP · error · RuntimeException

could not find matching word from lattice in parse…

Error message

could not find matching word from lattice in parse reconstruction

What it means

During parse reconstruction from a word lattice, ExhaustivePCFGParser searches the lattice for a node matching the word at a given position. If no lattice node matches (wordNode remains null), it throws this RuntimeException, indicating the lattice and the reconstructed parse are inconsistent.

Solutions

  1. Ensure the lattice words exactly match the tokens passed to the parser (same strings and tokenization).
  2. Rebuild the lattice so every position covered by the parse has a matching word node with consistent start/end positions.
  3. Verify lattice construction code (word values, positions) before parsing; validate with the library's lattice-reading utilities.

Example fix

// before
parserQuery.parse(latticeWords); // lattice built with different tokenizer
// after
List<HasWord> tokens = tokenizer.tokenize(text); // same tokenizer used to build lattice
List<WordLattice> lat = latticeBuilder.build(tokens);
parserQuery.setInputs(lat, tokens);
Defensive patterns

Strategy: validation

Validate before calling

// before parsing with a lattice, verify coverage
for (int i = 0; i < tokens.size(); i++)
  if (!latticeWordAtCovers(lat, i, tokens.get(i).word()))
    throw new IllegalArgumentException("lattice missing word at pos " + i);

Try / catch

try { Tree t = pq.getBestParse(); } catch (RuntimeException e) { if (e.getMessage().contains("lattice")) rebuildLattice(); else throw e; }

Prevention

When it happens

Trigger: Calling getBestParse()/parse reconstruction on a sentence parsed with a lattice (setInput with a List<HasWord> lattice / SRILM-style lattice) where the word expected at position `start` does not exactly match any node in the lattice segment (e.g. word string, start/end positions mismatch).

Common situations: Using lattice input where the lattice was built with different tokenization or normalization than the tag sequence the parser emits; malformed lattice edges; mismatched word/POS naming conventions.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10). Data as JSON: /api/errors/8d52db58092ac00d. Report an issue: GitHub.

Appendix: source

Thrown at src/edu/stanford/nlp/parser/lexparser/ExhaustivePCFGParser.java:1590

        } else if (lr != null) {
          List<LatticeEdge> latticeEdges = lr.getEdgesOverSpan(start, end);
          for (LatticeEdge edge : latticeEdges) {
            IntTaggedWord itw = new IntTaggedWord(edge.word, stateIndex.get(goal), wordIndex, tagIndex);

            float tagScore = (floodTags) ? -1000.0f : lex.score(itw, start, edge.word, null);
            if (matches(bestScore, tagScore + (float) edge.weight)) {
              wordNode = tf.newLeaf(edge.word);
              if(wordNode.label() instanceof CoreLabel) {
              	CoreLabel cl = (CoreLabel) wordNode.label();
              	cl.setBeginPosition(start);
              	cl.setEndPosition(end);
              }
              break;
            }
          }
          if (wordNode == null) {
            throw new RuntimeException("could not find matching word from lattice in parse reconstruction");
          }

        } else {
          throw new RuntimeException("attempt to get word when sentence and lattice are null!");
        }
        Tree tagNode = tf.newTreeNode(goalStr, Collections.singletonList(wordNode));
        tagNode.setScore(bestScore);
        if (originalTags[start] != null) {
          tagNode.label().setValue(originalTags[start].tag());
        }
        return tagNode;
      } else {  // normal lexicon is single words case
        IntTaggedWord tagging = new IntTaggedWord(words[start], tagIndex.indexOf(goalStr));
        String contextStr = getCoreLabel(start).originalText();
        float tagScore = lex.score(tagging, start, wordIndex.get(words[start]), contextStr);
        if (tagScore > Float.NEGATIVE_INFINITY || floodTags) {
          // return a pre-terminal tree
          CoreLabel terminalLabel = getCoreLabel(start);

View on GitHub (pinned to 1b7edd19c4)