Hmbown/CodeWhale · error · anyhow::Error

timed out waiting for runtime API bridge at

Error message

timed out waiting for runtime API bridge at {}/health

What it means

The app-server polls the Runtime API bridge's `/health` endpoint every 50 ms until a deadline; if the endpoint never returns a successful response in time, startup fails with this timeout. It means the runtime process did not come up, is listening on a different URL, or is wedged.

Solutions

  1. Check the runtime process is actually running and listening on base_url (curl the /health endpoint manually).
  2. Check for port conflicts (`address already in use`) or a wrong port in the runtime configuration.
  3. Inspect runtime stderr/logs for a startup crash.
  4. Increase the health-wait deadline if the runtime legitimately takes long to boot.
Defensive patterns

Strategy: retry

Validate before calling

// probe before relying on the bridge
let ok = reqwest::get(format!("{base}/health")).await.ok()
    .map(|r| r.status().is_success()).unwrap_or(false);
if !ok { eprintln!("runtime bridge not healthy yet"); }

Try / catch

// wrap launch with retry/backoff on timeout
match start_app_server().await {
    Err(e) if e.to_string().contains("timed out waiting for runtime API bridge") => {
        // inspect runtime logs, then retry once with a longer deadline
    }
    Err(e) => return Err(e),
    Ok(v) => Ok(v),
}

Prevention

When it happens

Trigger: `wait_for_health`-style polling loop sees non-success HTTP statuses or connection errors from `GET {base_url}/health` until `Instant::now() >= deadline`.

Common situations: Runtime binary fails to start (missing binary, port conflict), slow cold start exceeding the deadline, or base_url misconfigured to the wrong port.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/23e266d6b45bc388. Report an issue: GitHub.

Appendix: source

Thrown at crates/app-server/src/lib.rs:1597

        let deadline = Instant::now() + Duration::from_secs(15);
        loop {
            if let Some(child) = self.child.as_mut()
                && let Some(status) = child.try_wait()?
            {
                return Err(anyhow!(
                    "runtime API bridge exited before becoming ready (status {status})"
                ));
            }

            match self
                .client
                .get(format!("{}/health", self.base_url))
                .send()
                .await
            {
                Ok(response) if response.status().is_success() => return Ok(()),
                _ if Instant::now() >= deadline => {
                    bail!(
                        "timed out waiting for runtime API bridge at {}/health",
                        self.base_url
                    )
                }
                _ => tokio::time::sleep(Duration::from_millis(50)).await,
            }
        }
    }

    fn authed(&self, builder: reqwest::RequestBuilder) -> reqwest::RequestBuilder {
        match self.auth_token.as_deref() {
            Some(token) => builder.bearer_auth(token),
            None => builder,
        }
    }

    async fn request_json(&self, builder: reqwest::RequestBuilder) -> Result<Value> {
        let response = builder.send().await?;

View on GitHub (pinned to 73e0f67d83)