mirror of
https://github.com/openai/codex.git
synced 2026-11-10 21:00:47 +00:00
Treat workspace access denials as terminal errors (#60480)
## Why A `403` with `codex_workspace_access_denied` indicates that the account cannot use Codex in the selected workspace. Retrying or falling back to HTTP does not resolve that denial. ## What changed Map `codex_workspace_access_denied` and `invalid_workspace_selected` responses to a shared workspace access denial error, and rename the error variant to reflect its broader scope. Keep workspace denials excluded from compaction model fallback. ## Testing Extend API error mapping tests to cover the new code on `403` and preserve ordinary handling for `503`. Add WebSocket coverage verifying that an explicit workspace access denial does not trigger HTTP fallback. GitOrigin-RevId: e601a22a0fa783a4ce5401a98ff9c8d3d9d1b074
This commit is contained in:
@@ -290,9 +290,10 @@ fn map_api_error_details(err: ApiError) -> CodexErr {
|
||||
});
|
||||
let code = body_code.or(response.identity_error_code.as_deref());
|
||||
match (status, code) {
|
||||
(http::StatusCode::FORBIDDEN, Some("invalid_workspace_selected")) => {
|
||||
CodexErrorDetails::InvalidWorkspaceSelected(response).into()
|
||||
}
|
||||
(
|
||||
http::StatusCode::FORBIDDEN,
|
||||
Some("invalid_workspace_selected" | "codex_workspace_access_denied"),
|
||||
) => CodexErrorDetails::WorkspaceAccessDenied(response).into(),
|
||||
(http::StatusCode::FORBIDDEN, Some("access_program_not_enabled")) => {
|
||||
CodexErrorDetails::AccessProgramNotEnabled(ProviderRejection::Http(
|
||||
response,
|
||||
|
||||
@@ -814,12 +814,15 @@ fn only_an_explicit_workspace_403_stops_retries() {
|
||||
use http::StatusCode;
|
||||
let provider = r#"{"error":{"code":"invalid_workspace_selected"}}"#;
|
||||
let detail = r#"{"detail":{"code":"invalid_workspace_selected"}}"#;
|
||||
let access_denied = r#"{"detail":{"code":"codex_workspace_access_denied"}}"#;
|
||||
let other = r#"{"detail":{"code":"route_rate_limited"}}"#;
|
||||
let workspace_header =
|
||||
http::HeaderValue::from_str(&base64::engine::general_purpose::STANDARD.encode(provider))
|
||||
.unwrap();
|
||||
for (status, body, with_header, terminal) in [
|
||||
(StatusCode::FORBIDDEN, detail, false, true),
|
||||
(StatusCode::FORBIDDEN, access_denied, false, true),
|
||||
(StatusCode::SERVICE_UNAVAILABLE, access_denied, false, false),
|
||||
(StatusCode::FORBIDDEN, provider, false, true),
|
||||
(StatusCode::FORBIDDEN, "", true, true),
|
||||
(StatusCode::FORBIDDEN, "", false, false),
|
||||
@@ -845,10 +848,7 @@ fn only_an_explicit_workspace_403_stops_retries() {
|
||||
retry_after: None,
|
||||
}));
|
||||
assert_eq!(
|
||||
matches!(
|
||||
err.details(),
|
||||
CodexErrorDetails::InvalidWorkspaceSelected(_)
|
||||
),
|
||||
matches!(err.details(), CodexErrorDetails::WorkspaceAccessDenied(_)),
|
||||
terminal,
|
||||
"{err}"
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user