zeroclaw-labs/zeroclaw · error · anyhow::Error

OpenAI Codex endpoint override cannot be empty

Error message

OpenAI Codex endpoint override cannot be empty

What it means

When an endpoint override (provider_api_url) is configured for the openai-codex provider, build_responses_url trims it and rejects an empty or whitespace-only value instead of silently falling back to the default Responses URL. The provider fails fast at construction time (new -> resolve_responses_url -> build_responses_url). The fix is to delete the override, not to blank it.

Source

Thrown at crates/zeroclaw-providers/src/openai_codex.rs:162

                .connect_timeout(std::time::Duration::from_secs(10))
                .read_timeout(std::time::Duration::from_secs(300))
                .build()
                .unwrap_or_else(|_| Client::new()),
        })
    }
}

fn default_zeroclaw_dir() -> PathBuf {
    directories::UserDirs::new().map_or_else(
        || PathBuf::from(".zeroclaw"),
        |dirs| dirs.home_dir().join(".zeroclaw"),
    )
}

fn build_responses_url(base_or_endpoint: &str) -> anyhow::Result<String> {
    let candidate = base_or_endpoint.trim();
    if candidate.is_empty() {
        anyhow::bail!("OpenAI Codex endpoint override cannot be empty");
    }

    let mut parsed = reqwest::Url::parse(candidate).map_err(|_| {
        ::zeroclaw_log::record!(
            WARN,
            ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Reject)
                .with_outcome(::zeroclaw_log::EventOutcome::Failure)
                .with_attrs(::serde_json::json!({"candidate": candidate})),
            "openai_codex: endpoint override is not a valid URL"
        );
        anyhow::Error::msg("OpenAI Codex endpoint override must be a valid URL")
    })?;

    match parsed.scheme() {
        "http" | "https" => {}
        _ => anyhow::bail!("OpenAI Codex endpoint override must use http:// or https://"),
    }

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Remove the empty api_url/provider_api_url key entirely — resolve_responses_url then uses DEFAULT_CODEX_RESPONSES_URL.
  2. Or set a real http(s) URL; a missing /responses suffix is appended automatically.
  3. Lint config/env for empty-string endpoint overrides before deploy.

Example fix

# before
[providers.models.openai-codex.main]
api_url = ""

# after — key removed, default Responses endpoint is used
[providers.models.openai-codex.main]
model = "gpt-5-codex"
Defensive patterns

Strategy: validation

Validate before calling

// Treat an unset override as absent, never as empty string
let api_url = configured_api_url.map(str::trim).filter(|s| !s.is_empty());
// api_url == None now yields the default Responses URL

Prevention

When it happens

Trigger: Setting the codex provider's api_url/provider_api_url to "" or " " in config or environment; a template config with an empty placeholder value that was deployed as-is.

Common situations: Copy-pasted config templates with empty url fields; setting an env var to empty string intending to 'unset' it; CI injecting an empty variable for the override.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/44a1d9991dd3703e. Report an issue: GitHub.