diff --git a/codex-rs/codex-client/src/default_client.rs b/codex-rs/codex-client/src/default_client.rs index 4e328f7ae7..76ea258f57 100644 --- a/codex-rs/codex-client/src/default_client.rs +++ b/codex-rs/codex-client/src/default_client.rs @@ -111,10 +111,41 @@ impl CodexRequestBuilder { } pub async fn send(self) -> Result { + let residency_header = self + .builder + .try_clone() + .and_then(|builder| builder.build().ok()) + .and_then(|request| { + request + .headers() + .get("x-openai-internal-codex-residency") + .and_then(|value| value.to_str().ok()) + .map(std::borrow::ToOwned::to_owned) + }); let headers = trace_headers(); match self.builder.headers(headers).send().await { Ok(response) => { + if is_codex_responses_path(&self.url) && response.status().as_u16() == 401 { + let cf_ray = response + .headers() + .get("cf-ray") + .and_then(|value| value.to_str().ok()); + let auth_error = response + .headers() + .get("x-openai-authorization-error") + .and_then(|value| value.to_str().ok()); + tracing::info!( + method = %self.method, + url = %self.url, + status = %response.status(), + residency_header_present = residency_header.is_some(), + residency_header_value = ?residency_header, + cf_ray, + auth_error, + "Codex responses request returned unauthorized" + ); + } tracing::debug!( method = %self.method, url = %self.url, @@ -141,6 +172,11 @@ impl CodexRequestBuilder { } } +fn is_codex_responses_path(url: &str) -> bool { + url.contains("/backend-api/codex/responses") + || url.contains("/chat/backend/api/codex/responses") +} + struct HeaderMapInjector<'a>(&'a mut HeaderMap); impl<'a> Injector for HeaderMapInjector<'a> { diff --git a/codex-rs/core/src/default_client.rs b/codex-rs/core/src/default_client.rs index 94ecd8fcec..65509d1350 100644 --- a/codex-rs/core/src/default_client.rs +++ b/codex-rs/core/src/default_client.rs @@ -84,6 +84,13 @@ pub fn set_default_client_residency_requirement(enforce_residency: Option reqwest::Client { let value = match requirement { ResidencyRequirement::Us => HeaderValue::from_static("us"), }; + tracing::debug!( + header_name = RESIDENCY_HEADER_NAME, + header_value = ?value, + "Applying residency header to default HTTP client" + ); headers.insert(RESIDENCY_HEADER_NAME, value); } let ua = get_codex_user_agent();