stanfordnlp/CoreNLP · error · IllegalArgumentException
Illegal quantifier at beginning of pattern
Error message
Illegal quantifier at beginning of pattern: ${str} What it means
Thrown while compiling a formatter pattern when a quantifier (e.g. digits or repetition syntax like '2' or '.') appears before any format component has been built. The pattern grammar requires at least one component before a quantifier can attach to it.
Solutions
- Fix the pattern so it begins with a format component (e.g. yyyy, dd, MM) before any quantifier.
- Check the pattern for truncation or stray leading digits/punctuation.
- Add a pre-compile regex sanity check on pattern strings loaded from config.
Example fix
// before expr: "2dd/MM/yyyy" // after expr: "dd/MM/yyyy"
Defensive patterns
Strategy: validation
Validate before calling
static boolean patternStartsWithComponent(String p) {
// must begin with a letter (format directive) not a quantifier/digit
return p != null && p.matches("^[A-Za-z].*");
} Try / catch
try {
compilePattern(expr);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Illegal quantifier at beginning")) {
throw new IllegalArgumentException("Check formatter pattern for leading quantifier: " + expr, e);
} else throw e;
} Prevention
- Start every formatter pattern with a format directive (yyyy, dd, MM...).
- Lint patterns in .sutime.txt files at build time.
- Beware truncation when patterns are built dynamically.
When it happens
Trigger: A rule formatter pattern that starts with a quantifier character, e.g. expr starting with a digit or repetition marker like "2dd/MM" instead of "dd/MM".
Common situations: Typos in .sutime.txt formatter patterns; accidentally truncating the pattern so only a quantifier remains; copy/paste dropping the first format letters.
Related errors
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/af76bc5c7df8a6fe.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/time/TimeFormatter.java:908
appendComponent(new TimeZoneIdComponent(), true);
}
protected void appendTimeZoneName() {
builder.appendTimeZoneName();
// TODO: TimeZoneName
appendComponent(new TimeZoneComponent(locale), true);
}
protected void appendTimeZoneShortName() {
builder.appendTimeZoneShortName();
// TODO: TimeZoneName
appendComponent(new TimeZoneComponent(locale), true);
}
protected void appendQuantifier(String str) {
if (pieces.size() > 0) {
FormatComponent last = pieces.get(pieces.size() - 1);
last.appendQuantifier(str);
} else {
throw new IllegalArgumentException("Illegal quantifier at beginning of pattern: " + str);
}
}
protected void appendGroupStart() { appendRegexPart("(?:");}
protected void appendGroupEnd() { appendRegexPart(")"); }
protected void appendLiteral(char c) {
builder.appendLiteral(c);
appendLiteralField(String.valueOf(c));}
protected void appendLiteral(String s) {
builder.appendLiteral(s);
appendLiteralField(s); }
}
private static void parsePatternTo(FormatterBuilder builder, String pattern) {
int length = pattern.length();View on GitHub (pinned to 1b7edd19c4)