stanfordnlp/CoreNLP · error · ParseException

Variable was referenced before it was declared

Error message

Variable ${name} was referenced before it was declared

What it means

A tregex pattern can reference a previously declared variable with ${name} (back-reference). This ParseException is thrown when ${name} is used but that variable was never declared with =name earlier in the pattern.

Solutions

  1. Add the missing declaration =name before the reference
  2. Fix the variable name so the reference matches an existing declaration
  3. Validate variable usage/declaration consistency before compiling

Example fix

// before
String pattern = "A < B ${x}";
// after
String pattern = "A=${x} < B ${x}";
Defensive patterns

Strategy: validation

Validate before calling

Set<String> declared = new HashSet<>();
Matcher d = Pattern.compile("=(\\w+)").matcher(pattern);
while (d.find()) declared.add(d.group(1));
Matcher r = Pattern.compile("\\$\\{(\\w+)\\}").matcher(pattern);
while (r.find()) if (!declared.contains(r.group(1))) throw new IllegalArgumentException("undeclared: " + r.group(1));

Try / catch

try { TregexPattern.compile(pattern); } catch (ParseException e) { /* undeclared variable reference; add =name */ }

Prevention

When it happens

Trigger: Compiling a pattern containing ${name} with no preceding =name declaration; typos in variable names so the reference does not match the declaration.

Common situations: Typos or case mismatches between =Foo and ${foo}; reordered patterns where the declaration was deleted; generated queries with inconsistent variable naming.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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

Appendix: source

Thrown at src/edu/stanford/nlp/trees/tregex/TregexParser.java:298

if (!knownVariables.contains(linkedName.image)) {
          {if (true) throw new ParseException("Variable " + linkedName.image +
                                   " was referenced before it was declared");}
        }
        if (name != null) {
          if (knownVariables.contains(name.image)) {
            {if (true) throw new ParseException("Variable " + name.image + " has been declared twice, which makes no sense");}
          } else {
            knownVariables.add(name.image);
          }
        }
        link = true;
      break;
      }
    case 21:{
      jj_consume_token(21);
      name = jj_consume_token(IDENTIFIER);
if (!knownVariables.contains(name.image)) {
          {if (true) throw new ParseException("Variable " + name.image +
                                   " was referenced before it was declared");}
        }
      break;
      }
    default:
      jj_la1[10] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
DescriptionPattern ret = new DescriptionPattern(r, negateDesc, desc != null ? desc.image : null, name != null ? name.image : null, cat, basicCatFunction, varGroups, link, linkedName != null ? linkedName.image : null);
    {if ("" != null) return ret;}
    throw new Error("Missing return statement in function");
}

  final public TregexPattern ChildrenDisj() throws ParseException {TregexPattern child;
  List<TregexPattern> children = new ArrayList<TregexPattern>();
  // When we keep track of the known variables to assert that
  // variables are not redefined, or that links are only set to known

View on GitHub (pinned to 1b7edd19c4)