Remove OPENAI_BASE_URL config fallback (#16720)

The `OPENAI_BASE_URL` environment variable has been a significant
support issue, so we decided to deprecate it in favor of an
`openai_base_url` config key. We've had the deprecation warning in place
for about a month, so users have had time to migrate to the new
mechanism. This PR removes support for `OPENAI_BASE_URL` entirely.
This commit is contained in:
Eric Traut
2026-04-03 15:03:21 -07:00
committed by GitHub
Unverified
parent a70aee1a1e
commit 4b8bab6ad3
10 changed files with 44 additions and 164 deletions
+1 -18
View File
@@ -148,7 +148,6 @@ pub(crate) const DEFAULT_AGENT_MAX_DEPTH: i32 = 1;
pub(crate) const DEFAULT_AGENT_JOB_MAX_RUNTIME_SECONDS: Option<u64> = None;
pub const CONFIG_TOML_FILE: &str = "config.toml";
const OPENAI_BASE_URL_ENV_VAR: &str = "OPENAI_BASE_URL";
const RESERVED_MODEL_PROVIDER_IDS: [&str; 3] = [
OPENAI_PROVIDER_ID,
OLLAMA_OSS_PROVIDER_ID,
@@ -2306,24 +2305,8 @@ impl Config {
.openai_base_url
.clone()
.filter(|value| !value.is_empty());
let openai_base_url_from_env = std::env::var(OPENAI_BASE_URL_ENV_VAR)
.ok()
.filter(|value| !value.is_empty());
if openai_base_url_from_env.is_some() {
if openai_base_url.is_some() {
tracing::warn!(
env_var = OPENAI_BASE_URL_ENV_VAR,
"deprecated env var is ignored because `openai_base_url` is set in config.toml"
);
} else {
startup_warnings.push(format!(
"`{OPENAI_BASE_URL_ENV_VAR}` is deprecated. Set `openai_base_url` in config.toml instead."
));
}
}
let effective_openai_base_url = openai_base_url.or(openai_base_url_from_env);
let mut model_providers = built_in_model_providers(effective_openai_base_url);
let mut model_providers = built_in_model_providers(openai_base_url);
// Merge user-defined providers into the built-in list.
for (key, provider) in cfg.model_providers.into_iter() {
model_providers.entry(key).or_insert(provider);
+1 -36
View File
@@ -89,40 +89,6 @@ async fn responses_mode_stream_cli() {
// assert!(page.items[0].created_at.is_some(), "missing created_at");
}
/// Ensures `OPENAI_BASE_URL` still works as a deprecated fallback.
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn responses_mode_stream_cli_supports_openai_base_url_env_fallback() {
skip_if_no_network!();
let server = MockServer::start().await;
let repo_root = repo_root();
let sse = responses::sse(vec![
responses::ev_response_created("resp-1"),
responses::ev_assistant_message("msg-1", "hi"),
responses::ev_completed("resp-1"),
]);
let resp_mock = responses::mount_sse_once(&server, sse).await;
let home = TempDir::new().unwrap();
let bin = codex_utils_cargo_bin::cargo_bin("codex").unwrap();
let mut cmd = AssertCommand::new(bin);
cmd.timeout(Duration::from_secs(30));
cmd.arg("exec")
.arg("--skip-git-repo-check")
.arg("-C")
.arg(&repo_root)
.arg("hello?");
cmd.env("CODEX_HOME", home.path())
.env("OPENAI_API_KEY", "dummy")
.env("OPENAI_BASE_URL", format!("{}/v1", server.uri()));
let output = cmd.output().unwrap();
assert!(output.status.success());
let request = resp_mock.single_request();
assert_eq!(request.path(), "/v1/responses");
}
/// Ensures `openai_base_url` config override routes built-in openai provider requests.
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn responses_mode_stream_cli_supports_openai_base_url_config_override() {
@@ -275,8 +241,7 @@ async fn exec_cli_profile_applies_model_instructions_file() {
.arg(&repo_root)
.arg("hello?\n");
cmd.env("CODEX_HOME", home.path())
.env("OPENAI_API_KEY", "dummy")
.env("OPENAI_BASE_URL", format!("{}/v1", server.uri()));
.env("OPENAI_API_KEY", "dummy");
let output = cmd.output().unwrap();
println!("Status: {}", output.status);
-2
View File
@@ -26,7 +26,6 @@ fn persists_rollout_file_by_default() -> anyhow::Result<()> {
test.cmd()
.env("CODEX_RS_SSE_FIXTURE", &fixture)
.env("OPENAI_BASE_URL", "http://unused.local")
.arg("--skip-git-repo-check")
.arg("default persistence behavior")
.assert()
@@ -43,7 +42,6 @@ fn does_not_persist_rollout_file_in_ephemeral_mode() -> anyhow::Result<()> {
test.cmd()
.env("CODEX_RS_SSE_FIXTURE", &fixture)
.env("OPENAI_BASE_URL", "http://unused.local")
.arg("--skip-git-repo-check")
.arg("--ephemeral")
.arg("ephemeral behavior")
-17
View File
@@ -124,7 +124,6 @@ fn exec_resume_last_appends_to_existing_file() -> anyhow::Result<()> {
test.cmd()
.env("CODEX_RS_SSE_FIXTURE", &fixture)
.env("OPENAI_BASE_URL", "http://unused.local")
.arg("--skip-git-repo-check")
.arg("-C")
.arg(&repo_root)
@@ -143,7 +142,6 @@ fn exec_resume_last_appends_to_existing_file() -> anyhow::Result<()> {
test.cmd()
.env("CODEX_RS_SSE_FIXTURE", &fixture)
.env("OPENAI_BASE_URL", "http://unused.local")
.arg("--skip-git-repo-check")
.arg("-C")
.arg(&repo_root)
@@ -178,7 +176,6 @@ fn exec_resume_last_accepts_prompt_after_flag_in_json_mode() -> anyhow::Result<(
test.cmd()
.env("CODEX_RS_SSE_FIXTURE", &fixture)
.env("OPENAI_BASE_URL", "http://unused.local")
.arg("--skip-git-repo-check")
.arg("-C")
.arg(&repo_root)
@@ -197,7 +194,6 @@ fn exec_resume_last_accepts_prompt_after_flag_in_json_mode() -> anyhow::Result<(
test.cmd()
.env("CODEX_RS_SSE_FIXTURE", &fixture)
.env("OPENAI_BASE_URL", "http://unused.local")
.arg("--skip-git-repo-check")
.arg("-C")
.arg(&repo_root)
@@ -232,7 +228,6 @@ fn exec_resume_last_respects_cwd_filter_and_all_flag() -> anyhow::Result<()> {
let prompt_a = format!("echo {marker_a}");
test.cmd()
.env("CODEX_RS_SSE_FIXTURE", &fixture)
.env("OPENAI_BASE_URL", "http://unused.local")
.arg("--skip-git-repo-check")
.arg("-C")
.arg(dir_a.path())
@@ -244,7 +239,6 @@ fn exec_resume_last_respects_cwd_filter_and_all_flag() -> anyhow::Result<()> {
let prompt_b = format!("echo {marker_b}");
test.cmd()
.env("CODEX_RS_SSE_FIXTURE", &fixture)
.env("OPENAI_BASE_URL", "http://unused.local")
.arg("--skip-git-repo-check")
.arg("-C")
.arg(dir_b.path())
@@ -268,7 +262,6 @@ fn exec_resume_last_respects_cwd_filter_and_all_flag() -> anyhow::Result<()> {
let prompt_b_touch = format!("echo {marker_b_touch}");
test.cmd()
.env("CODEX_RS_SSE_FIXTURE", &fixture)
.env("OPENAI_BASE_URL", "http://unused.local")
.arg("--skip-git-repo-check")
.arg("-C")
.arg(dir_b.path())
@@ -287,7 +280,6 @@ fn exec_resume_last_respects_cwd_filter_and_all_flag() -> anyhow::Result<()> {
let prompt_b2 = format!("echo {marker_b2}");
test.cmd()
.env("CODEX_RS_SSE_FIXTURE", &fixture)
.env("OPENAI_BASE_URL", "http://unused.local")
.arg("--skip-git-repo-check")
.arg("-C")
.arg(dir_a.path())
@@ -309,7 +301,6 @@ fn exec_resume_last_respects_cwd_filter_and_all_flag() -> anyhow::Result<()> {
let prompt_a2 = format!("echo {marker_a2}");
test.cmd()
.env("CODEX_RS_SSE_FIXTURE", &fixture)
.env("OPENAI_BASE_URL", "http://unused.local")
.arg("--skip-git-repo-check")
.arg("-C")
.arg(dir_a.path())
@@ -340,7 +331,6 @@ fn exec_resume_accepts_global_flags_after_subcommand() -> anyhow::Result<()> {
// Seed a session.
test.cmd()
.env("CODEX_RS_SSE_FIXTURE", &fixture)
.env("OPENAI_BASE_URL", "http://unused.local")
.arg("--skip-git-repo-check")
.arg("echo seed-resume-session")
.assert()
@@ -349,7 +339,6 @@ fn exec_resume_accepts_global_flags_after_subcommand() -> anyhow::Result<()> {
// Resume while passing global flags after the subcommand to ensure clap accepts them.
test.cmd()
.env("CODEX_RS_SSE_FIXTURE", &fixture)
.env("OPENAI_BASE_URL", "http://unused.local")
.arg("resume")
.arg("--last")
.arg("--json")
@@ -378,7 +367,6 @@ fn exec_resume_by_id_appends_to_existing_file() -> anyhow::Result<()> {
test.cmd()
.env("CODEX_RS_SSE_FIXTURE", &fixture)
.env("OPENAI_BASE_URL", "http://unused.local")
.arg("--skip-git-repo-check")
.arg("-C")
.arg(&repo_root)
@@ -401,7 +389,6 @@ fn exec_resume_by_id_appends_to_existing_file() -> anyhow::Result<()> {
test.cmd()
.env("CODEX_RS_SSE_FIXTURE", &fixture)
.env("OPENAI_BASE_URL", "http://unused.local")
.arg("--skip-git-repo-check")
.arg("-C")
.arg(&repo_root)
@@ -434,7 +421,6 @@ fn exec_resume_preserves_cli_configuration_overrides() -> anyhow::Result<()> {
test.cmd()
.env("CODEX_RS_SSE_FIXTURE", &fixture)
.env("OPENAI_BASE_URL", "http://unused.local")
.arg("--skip-git-repo-check")
.arg("--sandbox")
.arg("workspace-write")
@@ -456,7 +442,6 @@ fn exec_resume_preserves_cli_configuration_overrides() -> anyhow::Result<()> {
let output = test
.cmd()
.env("CODEX_RS_SSE_FIXTURE", &fixture)
.env("OPENAI_BASE_URL", "http://unused.local")
.arg("--skip-git-repo-check")
.arg("--sandbox")
.arg("workspace-write")
@@ -510,7 +495,6 @@ fn exec_resume_accepts_images_after_subcommand() -> anyhow::Result<()> {
test.cmd()
.env("CODEX_RS_SSE_FIXTURE", &fixture)
.env("OPENAI_BASE_URL", "http://unused.local")
.arg("--skip-git-repo-check")
.arg("-C")
.arg(&repo_root)
@@ -534,7 +518,6 @@ fn exec_resume_accepts_images_after_subcommand() -> anyhow::Result<()> {
let prompt2 = format!("echo {marker2}");
test.cmd()
.env("CODEX_RS_SSE_FIXTURE", &fixture)
.env("OPENAI_BASE_URL", "http://unused.local")
.arg("--skip-git-repo-check")
.arg("-C")
.arg(&repo_root)
+30 -80
View File
@@ -1,6 +1,5 @@
use std::collections::HashMap;
const OPENAI_BASE_URL_ENV_VAR: &str = "OPENAI_BASE_URL";
pub const FEEDBACK_DIAGNOSTICS_ATTACHMENT_FILENAME: &str = "codex-connectivity-diagnostics.txt";
const PROXY_ENV_VARS: &[&str] = &[
"HTTP_PROXY",
@@ -58,13 +57,6 @@ impl FeedbackDiagnostics {
});
}
if let Some(value) = env.get(OPENAI_BASE_URL_ENV_VAR).map(String::as_str) {
diagnostics.push(FeedbackDiagnostic {
headline: "OPENAI_BASE_URL is set and may affect connectivity.".to_string(),
details: vec![format!("{OPENAI_BASE_URL_ENV_VAR} = {value}")],
});
}
Self { diagnostics }
}
@@ -112,38 +104,34 @@ mod tests {
),
("http_proxy", "proxy.example.com:8080"),
("all_proxy", "socks5h://all-proxy.example.com:1080"),
("OPENAI_BASE_URL", "https://example.com/v1?token=secret"),
]);
assert_eq!(
diagnostics,
FeedbackDiagnostics {
diagnostics: vec![
FeedbackDiagnostic {
headline:
"Proxy environment variables are set and may affect connectivity."
.to_string(),
details: vec![
"http_proxy = proxy.example.com:8080".to_string(),
"HTTPS_PROXY = https://user:password@secure-proxy.example.com:443?secret=1".to_string(),
"all_proxy = socks5h://all-proxy.example.com:1080".to_string(),
],
},
FeedbackDiagnostic {
headline: "OPENAI_BASE_URL is set and may affect connectivity.".to_string(),
details: vec![
"OPENAI_BASE_URL = https://example.com/v1?token=secret".to_string(),
],
},
],
diagnostics: vec![FeedbackDiagnostic {
headline: "Proxy environment variables are set and may affect connectivity."
.to_string(),
details: vec![
"http_proxy = proxy.example.com:8080".to_string(),
"HTTPS_PROXY = https://user:password@secure-proxy.example.com:443?secret=1"
.to_string(),
"all_proxy = socks5h://all-proxy.example.com:1080".to_string(),
],
},],
}
);
assert_eq!(
diagnostics.attachment_text(),
Some(
"Connectivity diagnostics\n\n- Proxy environment variables are set and may affect connectivity.\n - http_proxy = proxy.example.com:8080\n - HTTPS_PROXY = https://user:password@secure-proxy.example.com:443?secret=1\n - all_proxy = socks5h://all-proxy.example.com:1080\n- OPENAI_BASE_URL is set and may affect connectivity.\n - OPENAI_BASE_URL = https://example.com/v1?token=secret"
.to_string()
r#"Connectivity diagnostics
- Proxy environment variables are set and may affect connectivity.
- http_proxy = proxy.example.com:8080
- HTTPS_PROXY = https://user:password@secure-proxy.example.com:443?secret=1
- all_proxy = socks5h://all-proxy.example.com:1080"#
.to_string()
)
);
}
@@ -156,45 +144,18 @@ mod tests {
}
#[test]
fn collect_from_pairs_preserves_openai_base_url_literal_value() {
let diagnostics = FeedbackDiagnostics::collect_from_pairs([(
"OPENAI_BASE_URL",
"https://api.openai.com/v1/",
)]);
fn collect_from_pairs_preserves_whitespace_and_empty_values() {
let diagnostics =
FeedbackDiagnostics::collect_from_pairs([("HTTP_PROXY", " proxy with spaces ")]);
assert_eq!(
diagnostics,
FeedbackDiagnostics {
diagnostics: vec![FeedbackDiagnostic {
headline: "OPENAI_BASE_URL is set and may affect connectivity.".to_string(),
details: vec!["OPENAI_BASE_URL = https://api.openai.com/v1/".to_string()],
}],
}
);
}
#[test]
fn collect_from_pairs_preserves_whitespace_and_empty_values() {
let diagnostics = FeedbackDiagnostics::collect_from_pairs([
("HTTP_PROXY", " proxy with spaces "),
("OPENAI_BASE_URL", ""),
]);
assert_eq!(
diagnostics,
FeedbackDiagnostics {
diagnostics: vec![
FeedbackDiagnostic {
headline:
"Proxy environment variables are set and may affect connectivity."
.to_string(),
details: vec!["HTTP_PROXY = proxy with spaces ".to_string()],
},
FeedbackDiagnostic {
headline: "OPENAI_BASE_URL is set and may affect connectivity.".to_string(),
details: vec!["OPENAI_BASE_URL = ".to_string()],
},
],
headline: "Proxy environment variables are set and may affect connectivity."
.to_string(),
details: vec!["HTTP_PROXY = proxy with spaces ".to_string()],
},],
}
);
}
@@ -202,27 +163,16 @@ mod tests {
#[test]
fn collect_from_pairs_reports_values_verbatim() {
let proxy_value = "not a valid proxy";
let base_url_value = "hello";
let diagnostics = FeedbackDiagnostics::collect_from_pairs([
("HTTP_PROXY", proxy_value),
("OPENAI_BASE_URL", base_url_value),
]);
let diagnostics = FeedbackDiagnostics::collect_from_pairs([("HTTP_PROXY", proxy_value)]);
assert_eq!(
diagnostics,
FeedbackDiagnostics {
diagnostics: vec![
FeedbackDiagnostic {
headline:
"Proxy environment variables are set and may affect connectivity."
.to_string(),
details: vec!["HTTP_PROXY = not a valid proxy".to_string()],
},
FeedbackDiagnostic {
headline: "OPENAI_BASE_URL is set and may affect connectivity.".to_string(),
details: vec!["OPENAI_BASE_URL = hello".to_string()],
},
],
diagnostics: vec![FeedbackDiagnostic {
headline: "Proxy environment variables are set and may affect connectivity."
.to_string(),
details: vec!["HTTP_PROXY = not a valid proxy".to_string()],
},],
}
);
}
+4 -3
View File
@@ -650,8 +650,9 @@ mod tests {
let snapshot_with_diagnostics = CodexFeedback::new()
.snapshot(/*session_id*/ None)
.with_feedback_diagnostics(FeedbackDiagnostics::new(vec![FeedbackDiagnostic {
headline: "OPENAI_BASE_URL is set and may affect connectivity.".to_string(),
details: vec!["OPENAI_BASE_URL = https://example.com/v1".to_string()],
headline: "Proxy environment variables are set and may affect connectivity."
.to_string(),
details: vec!["HTTPS_PROXY = https://example.com:443".to_string()],
}]));
let attachments_with_diagnostics = snapshot_with_diagnostics.feedback_attachments(
@@ -674,7 +675,7 @@ mod tests {
assert_eq!(attachments_with_diagnostics[0].buffer, vec![1]);
assert_eq!(
attachments_with_diagnostics[1].buffer,
b"Connectivity diagnostics\n\n- OPENAI_BASE_URL is set and may affect connectivity.\n - OPENAI_BASE_URL = https://example.com/v1".to_vec()
b"Connectivity diagnostics\n\n- Proxy environment variables are set and may affect connectivity.\n - HTTPS_PROXY = https://example.com:443".to_vec()
);
assert_eq!(attachments_with_diagnostics[2].buffer, b"rollout".to_vec());
assert_eq!(
@@ -9,8 +9,8 @@ expression: popup
• codex-connectivity-diagnostics.txt
Connectivity diagnostics
- OPENAI_BASE_URL is set and may affect connectivity.
- OPENAI_BASE_URL = hello
- Proxy environment variables are set and may affect connectivity.
- HTTPS_PROXY = hello
1. Yes Share the current Codex session logs with the team for
troubleshooting.
@@ -1763,8 +1763,9 @@ async fn feedback_upload_consent_popup_snapshot() {
chat.current_rollout_path.clone(),
&codex_feedback::feedback_diagnostics::FeedbackDiagnostics::new(vec![
codex_feedback::feedback_diagnostics::FeedbackDiagnostic {
headline: "OPENAI_BASE_URL is set and may affect connectivity.".to_string(),
details: vec!["OPENAI_BASE_URL = hello".to_string()],
headline: "Proxy environment variables are set and may affect connectivity."
.to_string(),
details: vec!["HTTPS_PROXY = hello".to_string()],
},
]),
));
@@ -1783,8 +1784,9 @@ async fn feedback_good_result_consent_popup_includes_connectivity_diagnostics_fi
chat.current_rollout_path.clone(),
&codex_feedback::feedback_diagnostics::FeedbackDiagnostics::new(vec![
codex_feedback::feedback_diagnostics::FeedbackDiagnostic {
headline: "OPENAI_BASE_URL is set and may affect connectivity.".to_string(),
details: vec!["OPENAI_BASE_URL = hello".to_string()],
headline: "Proxy environment variables are set and may affect connectivity."
.to_string(),
details: vec!["HTTPS_PROXY = hello".to_string()],
},
]),
));
@@ -91,7 +91,6 @@ trust_level = "trusted"
.env("CODEX_HOME", codex_home.path())
.env("OPENAI_API_KEY", "dummy")
.env("CODEX_RS_SSE_FIXTURE", fixture_path)
.env("OPENAI_BASE_URL", "http://unused.local")
.output()
.context("failed to execute codex exec")?;
anyhow::ensure!(
-1
View File
@@ -134,7 +134,6 @@ describe("CodexExec", () => {
expect(spawnEnv.CODEX_HOME).toBe("/tmp/codex-home");
expect(spawnEnv.CUSTOM_ENV).toBe("custom");
expect(spawnEnv.CODEX_ENV_SHOULD_NOT_LEAK).toBeUndefined();
expect(spawnEnv.OPENAI_BASE_URL).toBeUndefined();
expect(spawnEnv.CODEX_API_KEY).toBe("test");
expect(spawnEnv.CODEX_INTERNAL_ORIGINATOR_OVERRIDE).toBeDefined();
expect(commandArgs).toContain("--config");