openai/codex · error · anyhow::Error

current-time request timed out after {}s

Error message

current-time request timed out after {}s

What it means

The Bedrock model provider refreshes credentials by shelling out to the AWS CLI, and refresh() hard-requires the configured auth command to be the literal string 'aws'; anything else — a script path, /usr/bin/aws, or a wrapper — is rejected with ErrorKind::InvalidInput before any subprocess runs (codex-rs/model-provider/src/amazon_bedrock/auth_refresh.rs:30). The restriction exists because the refresh logic parses `aws` CLI output specifically.

Source

Thrown at codex-rs/app-server/src/current_time.rs:129

                thread_id: thread_id.to_string(),
            }),
            /*thread_id*/ None,
        )
        .await;

    let result = match timeout_at(deadline, rx).await {
        Ok(Ok(Ok(result))) => result,
        Ok(Ok(Err(err))) => {
            bail!(
                "current-time request failed: code={} message={}",
                err.code,
                err.message
            );
        }
        Ok(Err(err)) => bail!("current-time request was canceled: {err}"),
        Err(_) => {
            let _canceled = outgoing.cancel_request(&request_id).await;
            bail!(
                "current-time request timed out after {}s",
                CURRENT_TIME_REQUEST_TIMEOUT.as_secs()
            );
        }
    };
    let response: CurrentTimeReadResponse =
        serde_json::from_value(result).context("invalid current-time response")?;

    DateTime::from_timestamp(response.current_time_at, 0)
        .ok_or_else(|| anyhow!("current-time response is outside the supported range"))
}

fn require_single_current_time_connection(connection_ids: &[ConnectionId]) -> Result<ConnectionId> {
    // External clocks are not interchangeable, so do not choose one silently.
    match connection_ids {
        [connection_id] => Ok(*connection_id),
        _ => bail!(
            "expected exactly one client subscribed to the thread, found {}",

View on GitHub (pinned to 339751715c)

Solutions

  1. Set the Bedrock auth refresh command to exactly `aws` (bare command name) and ensure AWS CLI v2 is on PATH.
  2. If you need a custom credential flow, use the provider's static credential or environment options instead of the refresh command.
  3. Verify with `command -v aws` inside the environment the process actually runs in.

Example fix

# before (model provider config)
auth_refresh_command = "/usr/local/bin/aws"
# after
auth_refresh_command = "aws"
Defensive patterns

Strategy: validation

Validate before calling

fn bedrock_refresh_config_ok(command: &str) -> bool {
    command == "aws" && which::which("aws").is_ok()
}

Try / catch

match refresh_handle.refresh().await {
    Err(e) if e.kind() == std::io::ErrorKind::InvalidInput
        && e.to_string().contains("must be `aws`") =>
    {
        // fix provider config: command must be the bare 'aws' CLI name
    }
    r => r?,
}

Prevention

When it happens

Trigger: recover_from_unauthorized calling refresh() after a 401/403 from Bedrock when the provider config's auth refresh command is not exactly 'aws' — an absolute path, a wrapper script, or a renamed binary.

Common situations: Hardened configs that replace command names with absolute paths; credential-vending wrapper scripts; config copied from examples that use a custom executable.

Understand the failure class

Related errors


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