stanfordnlp/CoreNLP · error · ParseException

Cannot add new variable names under negation. Node '

Error message

Cannot add new variable names under negation.  Node '

What it means

Semgrex forbids binding a NEW node variable name inside a negated context, because a match whose negation holds cannot consistently record variable bindings. If '=' name appears under negation and the name was not already bound earlier in the pattern, the parser throws ParseException.

Solutions

  1. Bind the variable outside the negation first (e.g. match '=x' in a positive clause, then negate a different part)
  2. Remove the '=name' binding from under the negation if the value is not needed
  3. Restructure the pattern to express the intended semantics without new bindings in '!' scope

Example fix

// before
SemgrexPattern p = SemgrexPattern.compile("{} !(>nsubj =subj)");
// after
SemgrexPattern p = SemgrexPattern.compile("{} >nsubj =subj"); // then filter subj in code, or bind earlier and negate a different element
Defensive patterns

Strategy: validation

Validate before calling

// reject '=name' occurrences inside '!( ... )' unless the name appears earlier outside negation
int neg = pattern.indexOf("!(");
if (neg >= 0) {
  String before = pattern.substring(0, neg);
  for (Matcher m = Pattern.compile("=(\\w+)").matcher(pattern.substring(neg)); m.find(); )
    if (!before.contains("=" + m.group(1))) throw new IllegalArgumentException("new variable under negation: " + m.group(1));
}

Try / catch

try {
  p = SemgrexPattern.compile(pattern);
} catch (ParseException e) {
  if (e.getMessage().startsWith("Cannot add new variable names under negation")) { /* hoist the binding out of the negation */ }
  throw e;
}

Prevention

When it happens

Trigger: Compiling patterns like '{} !(<nsubj =newName)' where '=newName' is first introduced inside the negated subexpression, i.e. the name is not in knownVariables.

Common situations: Writing negated relation patterns that also try to capture a node; converting positive patterns to negated ones by wrapping them in '!' without hoisting variable definitions.

Related errors


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

Appendix: source

Thrown at src/edu/stanford/nlp/semgraph/semgrex/SemgrexParser.jj:359

	( attr = <EMPTY> { attributes.setEmpty(true); } )
}

NodePattern Description(GraphRelation r) : {
	Token name = null;
	boolean link = false;
        NodeAttributes attributes = new NodeAttributes();
	NodePattern pat;
} {

	( "{" ( AddAttribute(attributes)
                (";" AddAttribute(attributes))* )? "}"

	(( ("=" { link = true; }) name = identifier() )
            {
              String nodeName = name.image;
              if (underNegation) {
                if (!knownVariables.contains(nodeName)) {
                  throw new ParseException("Cannot add new variable names under negation.  Node '" + nodeName + "' not seen before");
                }
              } else {
                knownVariables.add(nodeName);
              }
            }
	  )?
	)
  	{ pat = new NodePattern(r, underNodeNegation, attributes, link, name != null ? name.image : null);
	  return pat;
	}
}

Token identifier() : {
  Token t ;
}
{
  ( t = < UNIQ > | t = < IDENTIFIER > ) { return t; }
}

View on GitHub (pinned to 1b7edd19c4)