openai/codex · error · anyhow::Error

invalid glob pattern {pattern:?}: {err}

Error message

invalid glob pattern {pattern:?}: {err}

What it means

Strings prefixed with 'pattern:' are compiled by compile_glob_matcher via globset's GlobBuilder with backslash_escape(true) and literal_separator(true) for paths (false for query/header values). Patterns globset cannot parse — unclosed character classes like '[a-z', unterminated alternations like '{a,b', or bad backslash escapes — surface as 'invalid glob pattern {pattern:?}: {err}'.

Source

Thrown at codex-rs/network-proxy/src/mitm_hook.rs:533

    };
    if glob_pattern.is_empty() {
        return Err(anyhow!("glob pattern must not be empty"));
    }
    Ok(MatcherPattern::Glob(glob_pattern))
}

fn compile_glob_matcher(pattern: &str, literal_separator: bool) -> Result<CompiledGlobMatcher> {
    let mut builder = GlobBuilder::new(pattern);
    builder
        .backslash_escape(true)
        .literal_separator(literal_separator);
    builder
        .build()
        .map(|glob| CompiledGlobMatcher {
            pattern: pattern.to_string(),
            matcher: glob.compile_matcher(),
        })
        .map_err(|err| anyhow!("invalid glob pattern {pattern:?}: {err}"))
}

fn normalize_hook_host(host: &str) -> Result<String> {
    let normalized = normalize_host(host);
    if normalized.is_empty() {
        return Err(anyhow!("host must not be empty"));
    }
    if normalized.contains('*') {
        return Err(anyhow!(
            "MITM hook hosts must be exact hosts and cannot contain wildcards"
        ));
    }
    Ok(normalized)
}

fn normalize_methods(methods: &[String]) -> Result<Vec<String>> {
    methods
        .iter()

View on GitHub (pinned to 339751715c)

Solutions

  1. Fix the globset syntax: close every [class] and {alt,a,b}, and escape literal metacharacters with a backslash
  2. Wrap literal text containing glob metacharacters with the 'literal:' prefix instead, e.g. "literal:v[1]"
  3. Remember '*' does not cross '/' in path matchers (literal_separator = true) but does in query/header values
  4. Dry-run patterns with GlobBuilder::new(p).backslash_escape(true).literal_separator(true).build() before shipping config

Example fix

# before — unclosed alternation
path_prefixes = ["pattern:/api/{v"]

# after
path_prefixes = ["pattern:/api/{v1,v2}"]
Defensive patterns

Strategy: validation

Validate before calling

// Rust — pre-compile globs exactly like compile_glob_matcher does
use globset::GlobBuilder;
fn glob_ok(pattern: &str, literal_separator: bool) -> bool {
    GlobBuilder::new(pattern)
        .backslash_escape(true)
        .literal_separator(literal_separator)
        .build()
        .is_ok()
}
// paths use literal_separator = true; query/header values use false

Type guard

fn matcher_pattern_compiles(v: &str, literal_separator: bool) -> bool {
    match v.strip_prefix("pattern:") {
        Some(glob) => glob_ok(glob, literal_separator),
        None => true, // literal
    }
}

Try / catch

match compile_mitm_hooks(&config) {
    Ok(_) => {}
    Err(err) => eprintln!("{err:#}"), // embeds the bad pattern verbatim plus globset's parse error
}

Prevention

When it happens

Trigger: path_prefixes = ["pattern:[unclosed"], query allowed-values like "pattern:{a", or header matchers with a dangling backslash — any 'pattern:' entry for which GlobBuilder::build returns an error, from compile_path_matchers or compile_value_matchers.

Common situations: Assuming regex or plain shell-glob semantics instead of globset syntax; forgetting to escape '[' when matching a literal bracket; pasting complex alternations from other tools' configs.

Related errors


AI-assisted analysis of openai/codex@339751715c (2026-08-25). Data as JSON: /api/errors/eb9b88a28b93308a. Report an issue: GitHub.