{"record":{"id":"af76bc5c7df8a6fe","repo":"stanfordnlp/CoreNLP","slug":"illegal-quantifier-at-beginning-of-pattern-str","errorCode":null,"errorMessage":"Illegal quantifier at beginning of pattern: ${str}","messagePattern":"Illegal quantifier at beginning of pattern: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/time/TimeFormatter.java","lineNumber":908,"sourceCode":"      appendComponent(new TimeZoneIdComponent(), true);\n    }\n    protected void appendTimeZoneName() {\n      builder.appendTimeZoneName();\n      // TODO: TimeZoneName\n      appendComponent(new TimeZoneComponent(locale), true);\n    }\n    protected void appendTimeZoneShortName() {\n      builder.appendTimeZoneShortName();\n      // TODO: TimeZoneName\n      appendComponent(new TimeZoneComponent(locale), true);\n    }\n\n    protected void appendQuantifier(String str) {\n      if (pieces.size() > 0) {\n        FormatComponent last = pieces.get(pieces.size() - 1);\n        last.appendQuantifier(str);\n      } else {\n        throw new IllegalArgumentException(\"Illegal quantifier at beginning of pattern: \" + str);\n      }\n    }\n\n    protected void appendGroupStart() { appendRegexPart(\"(?:\");}\n\n    protected void appendGroupEnd() { appendRegexPart(\")\"); }\n\n    protected void appendLiteral(char c) {\n      builder.appendLiteral(c);\n      appendLiteralField(String.valueOf(c));}\n\n    protected void appendLiteral(String s) {\n      builder.appendLiteral(s);\n      appendLiteralField(s); }\n  }\n\n  private static void parsePatternTo(FormatterBuilder builder, String pattern) {\n    int length = pattern.length();","sourceCodeStart":890,"sourceCodeEnd":926,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/time/TimeFormatter.java#L890-L926","documentation":"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.","triggerScenarios":"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\".","commonSituations":"Typos in .sutime.txt formatter patterns; accidentally truncating the pattern so only a quantifier remains; copy/paste dropping the first format letters.","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."],"exampleFix":"// before\nexpr: \"2dd/MM/yyyy\"\n\n// after\nexpr: \"dd/MM/yyyy\"","handlingStrategy":"validation","validationCode":"static boolean patternStartsWithComponent(String p) {\n  // must begin with a letter (format directive) not a quantifier/digit\n  return p != null && p.matches(\"^[A-Za-z].*\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  compilePattern(expr);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"Illegal quantifier at beginning\")) {\n    throw new IllegalArgumentException(\"Check formatter pattern for leading quantifier: \" + expr, e);\n  } else throw e;\n}","preventionTips":["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."],"tags":["pattern-parsing","illegal-argument","formatter","sutime"],"backgroundTag":"invalid-regex-pattern","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}