stanfordnlp/CoreNLP · error · UnsupportedOperationException

String match result must be referred to by group id

Error message

String match result must be referred to by group id

What it means

In Expressions, a Tokens/GroupValue expression evaluated against a String match result must refer to capture groups by Integer group id. When the underlying value is a String (a group name) and the argument is a String-typed MatchResult wrapper that only supports numeric groups, groupNodes((String) v) is invalid for that result type and UnsupportedOperationException('String match result must be referred to by group id') is thrown.

Solutions

  1. Change the expression to reference the group by integer index instead of by name.
  2. Match against the token-sequence (CoreMap) matcher, which supports named group lookup, rather than a plain String match result.
  3. Guard evaluation: only resolve String group names when the MatchResult supports named groups.
  4. If using CoreNLP's Expression API, use TYPE_STRING/TOKENS group access consistent with the match result type you actually have.

Example fix

// before
Expressions.createTypedExpression("TOKENS", "$GROUPNAME").evaluate(env, stringMatchResult);
// after
Expressions.createTypedExpression("TOKENS", Integer.valueOf(1)).evaluate(env, stringMatchResult); // refer by group id
Defensive patterns

Strategy: type-guard

Validate before calling

// Ensure group refs are integer ids when matching against String results
if (groupRef instanceof String && matchResult instanceof java.util.regex.MatchResult) {
  throw new IllegalArgumentException("Use integer group ids with String match results");
}

Type guard

boolean groupRefIsValid(Expression e, Object matchResult) {
  Object v = ((Expressions.ValueExpression) e).get();
  return !(matchResult instanceof java.util.regex.MatchResult) || v instanceof Integer;
}

Try / catch

try {
  return expr.evaluate(env, matchResult);
} catch (UnsupportedOperationException e) {
  if (e.getMessage() != null && e.getMessage().contains("referred to by group id")) {
    throw new IllegalArgumentException("Convert named group refs to indices for String match results", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Evaluating an expression whose value is a named group reference (a String) with args[0] being a String match result (e.g. a regex match on a plain String rather than a token list), so the named-group lookup path is unavailable.

Common situations: TokensRegex expressions ported from token-level patterns to plain-string regex matching, where named groups used in TokensRegex are not supported by the String match result implementation.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at src/edu/stanford/nlp/ling/tokensregex/types/Expressions.java:625

      if (DIGITS_PATTERN.matcher(group).matches()) {
        Integer n = Integer.valueOf(group);
        return new RegexMatchVarExpression(n);
      } else {
        return new RegexMatchVarExpression(group);
      }
    }
    public Value evaluate(Env env, Object... args) {
      if (args != null && args.length > 0) {
        if (args[0] instanceof SequenceMatchResult) {
          SequenceMatchResult mr = (SequenceMatchResult) args[0];
          Object v = get();
          if (v instanceof String) {
            // TODO: depending if TYPE_STRING, use string version...
            return new PrimitiveValue<>(TYPE_TOKENS, mr.groupNodes((String) v));
          } else if (v instanceof Integer) {
            return new PrimitiveValue<>(TYPE_TOKENS, mr.groupNodes((Integer) v));
          } else {
            throw new UnsupportedOperationException("String match result must be referred to by group id");
          }
        } else if (args[0] instanceof MatchResult) {
          MatchResult mr = (MatchResult) args[0];
          Object v = get();
          if (v instanceof Integer) {
            String str = mr.group((Integer) get());
            return new PrimitiveValue<>(TYPE_STRING, str);
          } else {
            throw new UnsupportedOperationException("String match result must be referred to by group id");
          }
        }
      }
      return null;
    }
    public Expression assign(Expression expr) {
      return new VarAssignmentExpression(value.toString(), expr, false);
    }
  }

View on GitHub (pinned to 1b7edd19c4)