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
- Fix the globset syntax: close every [class] and {alt,a,b}, and escape literal metacharacters with a backslash
- Wrap literal text containing glob metacharacters with the 'literal:' prefix instead, e.g. "literal:v[1]"
- Remember '*' does not cross '/' in path matchers (literal_separator = true) but does in query/header values
- 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
- Dry-run every pattern: value through GlobBuilder with the same options the crate uses
- Use literal: for text containing glob metacharacters
- Remember * does not cross / in path patterns but does in query/header values
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
- glob pattern must not be empty
- path_prefixes must not contain empty entries
- network.mitm_hooks[{hook_index}].match.body is reserved for
- network.mitm_hooks[{hook_index}].host must not be empty
- expected exactly one of secret_env_var or secret_file
AI-assisted analysis of openai/codex@339751715c (2026-08-25).
Data as JSON: /api/errors/eb9b88a28b93308a.
Report an issue: GitHub.