openai/codex · error · std::io::Error

`bypass_hook_trust` override must be a boolean

Error message

`bypass_hook_trust` override must be a boolean

What it means

compile_denylist_globset builds the deny side of the domain policy with GlobalWildcard::Reject: a bare "*" — or any pattern that expands to one after normalization, such as "**" or "*." with an empty domain — is refused. The allowlist side compiles under GlobalWildcard::Allow and may carry "*" when the caller explicitly enables it; a global deny wildcard would silently defeat the allowlist, so the config is rejected up front with a pointer to scoped forms.

Source

Thrown at codex-rs/app-server/src/config_manager.rs:218

            request_overrides,
            typesafe_overrides,
            cwd,
        )
        .await
    }

    #[instrument(level = "trace", skip_all)]
    pub(crate) async fn load_with_cli_overrides(
        &self,
        cli_overrides: &[(String, TomlValue)],
        request_overrides: Option<HashMap<String, serde_json::Value>>,
        mut typesafe_overrides: ConfigOverrides,
        fallback_cwd: Option<PathBuf>,
    ) -> std::io::Result<Config> {
        let mut request_overrides = request_overrides.unwrap_or_default();
        if let Some(value) = request_overrides.remove("bypass_hook_trust") {
            typesafe_overrides.bypass_hook_trust = Some(value.as_bool().ok_or_else(|| {
                std::io::Error::new(
                    std::io::ErrorKind::InvalidData,
                    "`bypass_hook_trust` override must be a boolean",
                )
            })?);
        }
        let merged_cli_overrides = cli_overrides
            .iter()
            .cloned()
            .chain(
                request_overrides
                    .into_iter()
                    .map(|(key, value)| (key, json_to_toml(value))),
            )
            .collect::<Vec<_>>();
        let mut config = codex_core::config::ConfigBuilder::default()
            .codex_home(self.codex_home.clone())
            .cli_overrides(merged_cli_overrides)
            .loader_overrides(self.loader_overrides.clone())

View on GitHub (pinned to 339751715c)

Solutions

  1. Replace "*" = "deny" with explicit hosts or scoped wildcards: "*.example.com" matches subdomains only, "**.example.com" matches the apex and subdomains
  2. For block-everything-except-a-few, keep network mode limited and list the allows instead — deny is already the default
  3. Do not reach for a global wildcard at all; enumerate the hosts you actually want denied

Example fix

# config.toml — before
[network.domains]
"*" = "deny"

# after
[network.domains]
"*.tracker.example" = "deny"
"**.ads.example" = "deny"
"api.github.com" = "allow"
Defensive patterns

Strategy: validation

Validate before calling

fn deny_patterns_compilable(patterns: &[String]) -> bool {
    patterns.iter().all(|p| {
        let t = p.trim();
        !(t == "*" || t == "**" || t == "*." || t == "**.")
    })
}
let denied: Vec<String> = collect_deny_patterns(&config);
if !deny_patterns_compilable(&denied) {
    return Err(anyhow!("global wildcard not allowed on the deny side"));
}

Type guard

fn is_global_wildcard(pattern: &str) -> bool {
    matches!(pattern.trim(), "*" | "**" | "*." | "**.")
}

Prevention

When it happens

Trigger: config.toml with [network.domains] containing "*" = "deny" (or degenerate variants like "**" = "deny" or "*." = "deny"); compile_denylist_globset runs while the proxy builds its allow/deny globsets and bails before serving.

Common situations: Writing a global deny expecting default-deny semantics; not realizing limited mode is already deny-by-default with an allowlist; assuming * is a harmless shorthand for 'everything I did not allow'.

Related errors


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