risingwavelabs/risingwave · error

invalid regular expression option

Error message

invalid regular expression option: "{c}"

What it means

RisingWave parses a regex flags string character-by-character into `RegexpOptions` (case_insensitive, global, etc.). Any character other than the supported option letters is rejected with this error, since there is no silent-tolerance policy for unknown flags.

Solutions

  1. Use only supported flags: 'i' (case-insensitive), 'c' (case-sensitive), 'g' (global)
  2. Remove unsupported flags such as 'x', 's', 'n' from the flags string
  3. Rewrite the pattern to achieve the flag's effect (e.g. use (?s) inline constructs if supported by the regex crate)

Example fix

-- before
SELECT regexp_replace(s, 'a', 'b', 'x');
-- after
SELECT regexp_replace(s, 'a', 'b', 'g');
Defensive patterns

Strategy: validation

Validate before calling

const ok = /^[icg]*$/.test(flags); if (!ok) throw new Error(`unsupported regex flags: ${flags}`);

Try / catch

try { await rw.query(sql) } catch (e) { if (String(e).includes('invalid regular expression option')) { /* sanitize flags and retry */ } else throw e; }

Prevention

When it happens

Trigger: Passing a flags string to any regex function (regexp_match/replace/count/etc., or `RegexpOptions::from_str`) containing an unsupported character, e.g. 'x' (extended), 's', 'm' (multiline is 'm'? — only supported single-char options pass), or whitespace/typos.

Common situations: Porting regex flags from other engines (Postgres 'ng', PCRE 'x', JS 's'), typos like 'gg' or accidental spaces in the flag literal.

Understand the failure class

Background: "unknown output mode", "invalid value for flag", "expects true/false": fixing invalid flag value errors in CLI tools — this error's family across 24 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/8eb3ca1d2bd8a077. Report an issue: GitHub.

Appendix: source

Thrown at src/expr/impl/src/scalar/regexp.rs:129

    /// `g`
    global: bool,
}

impl FromStr for RegexpOptions {
    type Err = ExprError;

    fn from_str(s: &str) -> Result<Self> {
        let mut opts = Self::default();
        for c in s.chars() {
            match c {
                // Case sensitive matching here
                'c' => opts.case_insensitive = false,
                // Case insensitive matching here
                'i' => opts.case_insensitive = true,
                // Global matching here
                'g' => opts.global = true,
                _ => {
                    bail!("invalid regular expression option: \"{c}\"");
                }
            }
        }
        Ok(opts)
    }
}

#[function(
    // source ~ pattern
    "regexp_eq(varchar, varchar) -> boolean",
    prebuild = "RegexpContext::from_pattern($1)?"
)]
fn regexp_eq(text: &str, regex: &RegexpContext) -> bool {
    regex.regex.is_match(text).unwrap()
}

#[function(
    // regexp_match(source, pattern)

View on GitHub (pinned to 6469eb736d)