{"record":{"id":"bf80db0a1f524638","repo":"oxc-project/oxc","slug":"invalid-regular-expression-u-and-v-flags-shou","errorCode":null,"errorMessage":"Invalid regular expression: `u` and `v` flags should be used alone","messagePattern":"Invalid regular expression: `u` and `v` flags should be used alone","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"error","filePath":"crates/oxc_linter/src/rules/eslint/no_invalid_regexp.rs","lineNumber":31,"sourceCode":"    context::LintContext,\n    rule::{DefaultRuleConfig, Rule},\n};\n\n// Use the same prefix with `oxc_regular_expression` crate\nfn duplicated_flag_diagnostic(span: Span, flag: &str) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Invalid regular expression: Duplicated flag\")\n        .with_help(format!(\"Remove the duplicated '{flag}' flag from the regular expression flags\"))\n        .with_label(span.label(format!(\"flag '{flag}' already specified\")))\n}\n\nfn unknown_flag_diagnostic(span: Span, flag: &str) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Invalid regular expression: Unknown flag\")\n        .with_note(\"Valid flags are: d (indices), g (global), i (ignore case), m (multiline),\\n             s (dot all), u (unicode), v (unicode sets), y (sticky)\")\n        .with_label(span.label(format!(\"flag '{flag}' is not a valid regular expression flag\")))\n}\n\nfn invalid_unicode_flags_diagnostic(span: Span, is_u_specified: bool) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Invalid regular expression: `u` and `v` flags should be used alone\")\n        .with_help(\"Specify only one of 'u' or 'v' flags\")\n        .with_label(span.label(if is_u_specified {\n            \"the 'v' flag cannot be used when the 'u' flag is specified\"\n        } else {\n            \"the 'u' flag cannot be used when the 'v' flag is specified\"\n        }))\n}\n\n#[derive(Debug, Default, Clone, Deserialize)]\npub struct NoInvalidRegexp(Box<NoInvalidRegexpConfig>);\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Disallow invalid regular expression strings in RegExp constructors.\n    ///\n    /// ### Why is this bad?\n    ///","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/eslint/no_invalid_regexp.rs#L13-L49","documentation":"Diagnostic from oxlint's eslint/no-invalid-regexp rule (crates/oxc_linter/src/rules/eslint/no_invalid_regexp.rs:31). The 'u' (unicode) and 'v' (unicodeSets) modes are mutually exclusive parsing modes, so specifying both (/x/uv or new RegExp('x', 'uv')) is a SyntaxError per the ECMAScript spec. The label explains which of the two flags must be dropped based on which one was specified first.","triggerScenarios":"A regex literal with both flags: /[\\q{a}]/uv or /x/uv; a RegExp constructor call with 'uv' or 'vu' as the flags string. This often happens when adding the newer 'v' flag to a regex that already carried 'u'.","commonSituations":"Migrating a 'u'-flag regex to 'v' for set operations (difference, intersection, string literals in classes) and forgetting to delete 'u'; copy-pasting a 'v'-mode pattern like [\\q{ab}] into code whose flags string still says 'u'; enabling both flags 'to be safe'.","solutions":["Keep exactly one of the two: drop 'u' and keep 'v' when you need [\\q{...}] strings, set subtraction/intersection, or nested classes; keep 'u' for plain unicode mode","Remember 'v' is a superset of 'u' features, so /x/v alone is usually what you want when upgrading","Check flags strings assembled from constants for accidental inclusion of both letters"],"exampleFix":"// before\nconst re = /[\\q{abc}]/uv;\nconst re2 = new RegExp('x', 'uv');\n\n// after\nconst re = /[\\q{abc}]/v;\nconst re2 = new RegExp('x', 'v');","handlingStrategy":"validation","validationCode":"function assertUvExclusive(flags) {\n  if (flags.includes('u') && flags.includes('v')) {\n    throw new RangeError(\"'u' and 'v' regex flags are mutually exclusive\");\n  }\n}\nassertUvExclusive(modeFlags);\nconst re = new RegExp(pattern, modeFlags);","typeGuard":"function isUvCompatible(flags) {\n  return !(flags.includes('u') && flags.includes('v'));\n}","tryCatchPattern":"try {\n  new RegExp(pattern, flags);\n} catch (e) {\n  if (e instanceof SyntaxError && /u.*v|v.*u/i.test(e.message)) {\n    flags = flags.replace('u', ''); // keep v as the superset and retry\n    re = new RegExp(pattern, flags);\n  }\n}","preventionTips":["When upgrading a u-flag regex to v, delete u in the same commit","Treat v as a strict superset of u and default to v-only for new unicode regexes","Add a unit test over all regex flag constants asserting the u/v invariant"],"tags":["regex","lint","javascript","syntax-error","unicode","flags"],"backgroundTag":"invalid-regex-flags","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}