{"record":{"id":"a543a901fc4d3aaa","repo":"OpenAPITools/openapi-generator","slug":"pattern-must-follow-the-perl-pattern-modifiers-co","errorCode":null,"errorMessage":"Pattern must follow the Perl /pattern/modifiers convention. %s is not valid.","messagePattern":"Pattern must follow the Perl /pattern/modifiers convention\\. (.+?) is not valid\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java","lineNumber":1531,"sourceCode":"     * The OpenAPI pattern spec follows the Perl convention and style of modifiers. Python\n     * does not support this in as natural a way so it needs to convert it. See\n     * https://docs.python.org/2/howto/regex.html#compilation-flags for details.\n     *\n     * @param pattern (the String pattern to convert from python to Perl convention)\n     * @param vendorExtensions (list of custom x-* properties for extra functionality-see https://swagger.io/docs/specification/openapi-extensions/)\n     * @return void\n     * @throws IllegalArgumentException if pattern does not follow the Perl /pattern/modifiers convention\n     *\n     * Includes fix for issue #6675\n     */\n    public void postProcessPattern(String pattern, Map<String, Object> vendorExtensions) {\n        if (pattern != null) {\n            int i = pattern.lastIndexOf('/');\n\n            // TODO update the check below follow python convention\n            //Must follow Perl /pattern/modifiers convention\n            if (pattern.charAt(0) != '/' || i < 2) {\n                throw new IllegalArgumentException(\"Pattern must follow the Perl \"\n                        + \"/pattern/modifiers convention. \" + pattern + \" is not valid.\");\n            }\n\n            String regex = pattern.substring(1, i).replace(\"'\", \"\\\\'\");\n            List<String> modifiers = new ArrayList<String>();\n\n            for (char c : pattern.substring(i).toCharArray()) {\n                if (regexModifiers.containsKey(c)) {\n                    String modifier = regexModifiers.get(c);\n                    modifiers.add(modifier);\n                }\n            }\n\n            vendorExtensions.put(X_REGEX, regex.replace(\"\\\"\", \"\\\\\\\"\"));\n            vendorExtensions.put(X_PATTERN, pattern.replace(\"\\\"\", \"\\\\\\\"\"));\n            vendorExtensions.put(X_MODIFIERS, modifiers);\n        }\n    }","sourceCodeStart":1513,"sourceCodeEnd":1549,"githubUrl":"https://github.com/OpenAPITools/openapi-generator/blob/fcec517be3cf5b7964296bcba25fbc97541484e7/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java#L1513-L1549","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Write the pattern as a plain ECMAScript regex with no '/' delimiters, e.g. \"^/api/v[0-9]+$\" — the generator adds delimiters itself via addRegularExpressionDelimiter","If you keep Perl style, supply the complete form with a non-empty body and trailing delimiter, e.g. \"/^\\d{4}$/i\"","Delete degenerate patterns that are only slashes (\"/\", \"//\") from the schema"],"exampleFix":"# before (spec.yaml)\npattern: /api/v[0-9]+\n\n# after\npattern: ^/api/v[0-9]+","handlingStrategy":"validation","validationCode":"// JS: pre-scan the spec before generating\nfunction badPythonPattern(p) {\n  if (!p) return false;\n  if (p.startsWith('/')) {\n    const i = p.lastIndexOf('/');\n    if (i < 2) return true; // mirrors postProcessPattern: no body between delimiters\n  }\n  return false;\n}\nconst bad = collectPatterns(spec).filter(badPythonPattern);","typeGuard":null,"tryCatchPattern":"try { generator.generate(); } catch (IllegalArgumentException e) { if (e.getMessage().contains(\"Perl\")) { /* message embeds the offending pattern; fix that schema field */ } throw e; }","preventionTips":["Never put leading '/' delimiters in OpenAPI patterns; write bare ECMAScript regex","Add a CI lint step that scans schema patterns for leading slashes","Test-generate the spec with the exact Python generator in CI before merging"],"tags":["regex","openapi-spec","python","pattern-validation"],"backgroundTag":"invalid-regex-pattern","analyzedSha":"fcec517be3cf5b7964296bcba25fbc97541484e7","analyzedAt":"2026-08-22T11:13:11.613Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}