Kuberwastaken/claurst · error · anyhow::Error

Bridge register: server returned

Error message

Bridge register: server returned {}

What it means

`exchange_code` POSTs the authorization code (form-encoded) to the provider's token endpoint using reqwest. If the HTTP request itself fails at the transport layer (DNS, connect, TLS, timeout), the reqwest error is wrapped as "exchange_code: request failed: {}". This is a network-level failure, distinct from a non-2xx token response.

Solutions

  1. Check network connectivity to the token endpoint host (curl the metadata-resolved token_endpoint URL).
  2. Configure proxy env vars (HTTPS_PROXY/HTTP_PROXY) if behind a corporate proxy.
  3. Verify `session.metadata.token_endpoint` is the correct HTTPS URL from the provider's authorization-server metadata.
  4. Retry after confirming the provider's status page — transient outages produce this error too.
Defensive patterns

Strategy: retry

Try / catch

for attempt in 0..3 {
    match exchange_code(endpoint, &code, &verifier, &redirect_uri).await {
        Ok(t) => break t,
        Err(e) if e.to_string().contains("request failed") && attempt < 2 => {
            tokio::time::sleep(Duration::from_secs(2u64.pow(attempt))).await;
        }
        Err(e) => return Err(e),
    }
}

Prevention

When it happens

Trigger: `client.post(token_endpoint).form(&params).send().await` returns Err — unreachable host, DNS failure, TLS handshake failure, connection refused, or request timeout while contacting the token endpoint.

Common situations: Offline machine or broken DNS; corporate proxy required but not configured (HTTPS_PROXY unset); token endpoint hostname typo in provider metadata; TLS cert issues (self-signed MITM proxy); endpoint temporarily down.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10). Data as JSON: /api/errors/ab8501efdb62cf07. Report an issue: GitHub.

Appendix: source

Thrown at src-rust/crates/bridge/src/lib.rs:486

            .header("x-environment-runner-version", &self.config.runner_version)
            .json(&body)
            .send()
            .await
            .context("Bridge register: HTTP send failed")?;

        let status = resp.status().as_u16();
        match status {
            200 | 201 => {
                self.set_state(BridgeState::Connected);
                info!(session_id = %self.session_id, "Bridge session registered");
                Ok(())
            }
            401 | 403 => {
                self.set_state(BridgeState::Error(format!("Auth error: {status}")));
                anyhow::bail!("Bridge register: auth error ({})", status)
            }
            _ => {
                anyhow::bail!("Bridge register: server returned {}", status)
            }
        }
    }

    /// Deregister the session on clean shutdown.
    ///
    /// DELETE `/api/claude_code/sessions/{id}` — best-effort; errors are
    /// logged and swallowed so they don't block process exit.
    pub async fn deregister(&self) {
        let Some(token) = self.config.session_token.as_deref() else {
            return;
        };

        let url = format!(
            "{}/api/claude_code/sessions/{}",
            self.config.server_url, self.session_id
        );

View on GitHub (pinned to b0637c97ec)