openai/codex · error · io::Error

remote control URL cannot be a base

Error message

remote control URL cannot be a base

What it means

While appending the client id to the revoke URL, Url::path_segments_mut() failed because the configured remote-control base URL cannot be a base: it parses as a URL but has no hierarchical path to append segments to (url::Url::cannot_be_a_base(), true for opaque schemes like mailto: or data:). The InvalidInput error surfaces the misconfiguration before any request is sent; the same guard exists in environment_clients_url for the list path.

Source

Thrown at codex-rs/app-server-transport/src/transport/remote_control/clients.rs:144

    auth_manager: &Arc<AuthManager>,
    params: RemoteControlClientsRevokeParams,
) -> io::Result<RemoteControlClientsRevokeResponse> {
    if params.environment_id.is_empty() {
        return Err(io::Error::new(
            ErrorKind::InvalidInput,
            "remote control client revoke requires environmentId",
        ));
    }
    if params.client_id.is_empty() {
        return Err(io::Error::new(
            ErrorKind::InvalidInput,
            "remote control client revoke requires clientId",
        ));
    }
    let mut url = environment_clients_url(remote_control_url, &params.environment_id)?;
    url.path_segments_mut()
        .map_err(|()| {
            io::Error::new(
                ErrorKind::InvalidInput,
                "remote control URL cannot be a base",
            )
        })?
        .push(&params.client_id);
    let response = send_client_management_request(
        auth_manager,
        ClientManagementRequest::Revoke { url: &url },
        "revoke remote control client",
    )
    .await?;
    let ClientManagementResponse {
        status,
        headers,
        body,
    } = response;
    let body_preview = preview_remote_control_response_body(&body);
    ensure_success_response(status, &headers, &url, &body_preview, "client revoke")?;

View on GitHub (pinned to 339751715c)

Solutions

  1. Set remote_control_url to a full hierarchical URL, e.g. https://chatgpt.com/backend-api/
  2. Validate the configured URL early: Url::parse(...).map(|u| !u.cannot_be_a_base())
  3. Source the value only from the documented config key, not free-form env vars

Example fix

// before (config.toml)
remote_control_url = "chatgpt-remote:/control"

// after (config.toml)
remote_control_url = "https://chatgpt.com/backend-api/"
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_remote_control_url(s: &str) -> bool {
    url::Url::parse(s)
        .map(|u| !u.cannot_be_a_base() && matches!(u.scheme(), "http" | "https"))
        .unwrap_or(false)
}

Prevention

When it happens

Trigger: revoke_remote_control_client or list_remote_control_clients with a remote_control_url that Url::parse accepts but that is not an http(s)-style hierarchical URL — e.g. 'mailto:ops@example.com' or another opaque-scheme value coming from config or an env var.

Common situations: remote_control_url populated from a config template or env var carrying a placeholder or copied link; values that lost their https:// scheme; any non-hierarchical scheme slipping through earlier normalization.

Related errors


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