OpenAPITools/openapi-generator · error · IllegalArgumentException

Pattern must follow the Perl /pattern/modifiers convention.

Error message

Pattern must follow the Perl /pattern/modifiers convention. %s is not valid.

What it means

Python generators post-process every schema pattern (property.pattern, parameter.pattern, and array item patterns) in postProcessPattern. DefaultCodegen first routes the raw spec pattern through addRegularExpressionDelimiter; the Python override (AbstractPythonCodegen:1552) treats a pattern that already starts with '/' as pre-delimited Perl syntax and passes it through unchanged. postProcessPattern then requires charAt(0)=='/' AND a last '/' at index >= 2; anything else throws this IllegalArgumentException — effectively the pattern must be a complete /body/flags form with a non-empty body.

Source

Thrown at modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java:1531

     * The OpenAPI pattern spec follows the Perl convention and style of modifiers. Python
     * does not support this in as natural a way so it needs to convert it. See
     * https://docs.python.org/2/howto/regex.html#compilation-flags for details.
     *
     * @param pattern (the String pattern to convert from python to Perl convention)
     * @param vendorExtensions (list of custom x-* properties for extra functionality-see https://swagger.io/docs/specification/openapi-extensions/)
     * @return void
     * @throws IllegalArgumentException if pattern does not follow the Perl /pattern/modifiers convention
     *
     * Includes fix for issue #6675
     */
    public void postProcessPattern(String pattern, Map<String, Object> vendorExtensions) {
        if (pattern != null) {
            int i = pattern.lastIndexOf('/');

            // TODO update the check below follow python convention
            //Must follow Perl /pattern/modifiers convention
            if (pattern.charAt(0) != '/' || i < 2) {
                throw new IllegalArgumentException("Pattern must follow the Perl "
                        + "/pattern/modifiers convention. " + pattern + " is not valid.");
            }

            String regex = pattern.substring(1, i).replace("'", "\\'");
            List<String> modifiers = new ArrayList<String>();

            for (char c : pattern.substring(i).toCharArray()) {
                if (regexModifiers.containsKey(c)) {
                    String modifier = regexModifiers.get(c);
                    modifiers.add(modifier);
                }
            }

            vendorExtensions.put(X_REGEX, regex.replace("\"", "\\\""));
            vendorExtensions.put(X_PATTERN, pattern.replace("\"", "\\\""));
            vendorExtensions.put(X_MODIFIERS, modifiers);
        }
    }

View on GitHub (pinned to fcec517be3)

Solutions

  1. Write the pattern as a plain ECMAScript regex with no '/' delimiters, e.g. "^/api/v[0-9]+$" — the generator adds delimiters itself via addRegularExpressionDelimiter
  2. If you keep Perl style, supply the complete form with a non-empty body and trailing delimiter, e.g. "/^\d{4}$/i"
  3. Delete degenerate patterns that are only slashes ("/", "//") from the schema

Example fix

# before (spec.yaml)
pattern: /api/v[0-9]+

# after
pattern: ^/api/v[0-9]+
Defensive patterns

Strategy: validation

Validate before calling

// JS: pre-scan the spec before generating
function badPythonPattern(p) {
  if (!p) return false;
  if (p.startsWith('/')) {
    const i = p.lastIndexOf('/');
    if (i < 2) return true; // mirrors postProcessPattern: no body between delimiters
  }
  return false;
}
const bad = collectPatterns(spec).filter(badPythonPattern);

Try / catch

try { generator.generate(); } catch (IllegalArgumentException e) { if (e.getMessage().contains("Perl")) { /* message embeds the offending pattern; fix that schema field */ } throw e; }

Prevention

When it happens

Trigger: A spec pattern whose first character is '/' but which lacks a closing delimiter, leaving no regex body between slashes: pattern: "/", "//", or "/api/v[0-9]+" (a regex written to match a URL path). Plain ECMAScript patterns like "^\d+$" are auto-wrapped in delimiters and never reach the throw.

Common situations: Patterns copied from Perl/PCRE or Laravel-style docs where delimiters were half-removed; regexes intended to validate URL paths that begin with a literal '/'; specs manually prefixed with delimiters to please a different language generator.

Related errors


AI-assisted analysis of OpenAPITools/openapi-generator@fcec517be3 (2026-08-22). Data as JSON: /api/errors/a543a901fc4d3aaa. Report an issue: GitHub.