From faa154122fd8727066a3a70c52d5818d5170becc Mon Sep 17 00:00:00 2001 From: Parker Henderson Date: Tue, 14 Jul 2026 21:24:53 -0700 Subject: [PATCH 1/2] fix(auth): prioritize stored `org_name` over config `org` value --- src/auth.rs | 44 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/src/auth.rs b/src/auth.rs index 5044672..777bf9e 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -1176,11 +1176,17 @@ where api_key, api_url: base.api_url.clone().or_else(|| profile.api_url.clone()), app_url: base.app_url.clone().or_else(|| profile.app_url.clone()), - org_name: base - .org_name - .clone() - .or_else(|| cfg_org.clone()) - .or_else(|| profile.org_name.clone()), + org_name: if is_oauth { + base.org_name + .clone() + .or_else(|| profile.org_name.clone()) + .or_else(|| cfg_org.clone()) + } else { + base.org_name + .clone() + .or_else(|| cfg_org.clone()) + .or_else(|| profile.org_name.clone()) + }, is_oauth, }); } @@ -4538,6 +4544,34 @@ mod tests { assert_eq!(resolved.org_name.as_deref(), Some("local-org")); } + #[test] + fn resolve_auth_oauth_profile_org_overrides_stale_config_org() { + let mut base = make_base(); + base.profile = Some("default-profile".to_string()); + + let mut store = AuthStore::default(); + store.profiles.insert( + "default-profile".into(), + AuthProfile { + auth_kind: AuthKind::Oauth, + org_name: Some("profile-org".into()), + oauth_client_id: Some("bt_cli_default".to_string()), + ..Default::default() + }, + ); + let cfg_org = Some("local-org".to_string()); + + let resolved = resolve_auth_from_store_with_secret_lookup( + &base, + &store, + |_| Ok(Some("unused-profile-key".into())), + &cfg_org, + ) + .expect("resolve"); + assert!(resolved.is_oauth); + assert_eq!(resolved.org_name.as_deref(), Some("profile-org")); + } + #[test] fn resolve_auth_api_key_override_keeps_config_org() { let mut base = make_base(); From 2ff46b156ba6f037970298fa2226953a1fa6e026 Mon Sep 17 00:00:00 2001 From: Parker Henderson Date: Tue, 14 Jul 2026 21:28:33 -0700 Subject: [PATCH 2/2] Fix bt switch with stale org and OAuth profile config When switching projects without an explicit org, prefer the configured profile over the configured org for auth context. This prevents a stale config org from overriding an OAuth profile's stored org and causing project lookup to query the wrong workspace. --- src/switch.rs | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/switch.rs b/src/switch.rs index 35495bb..0f5a4c7 100644 --- a/src/switch.rs +++ b/src/switch.rs @@ -92,7 +92,7 @@ pub async fn run(base: BaseArgs, args: SwitchArgs) -> Result<()> { _ => { let mut b = base.clone(); if !has_api_key_override && b.org_name.is_none() && b.profile.is_none() { - b.org_name = current_cfg.org.clone(); + apply_current_switch_auth_context(&mut b, ¤t_cfg); } if !has_api_key_override && b.org_name.is_none() && b.profile.is_none() { let profiles = auth::list_profiles()?; @@ -230,6 +230,14 @@ pub(crate) fn select_scope() -> Result<(std::path::PathBuf, &'static str)> { } } +fn apply_current_switch_auth_context(base: &mut BaseArgs, current_cfg: &config::Config) { + if let Some(profile) = config::trimmed_option(current_cfg.profile.as_deref()) { + base.profile = Some(profile.to_string()); + } else { + base.org_name = current_cfg.org.clone(); + } +} + pub(crate) async fn validate_or_create_project( client: &ApiClient, name: &str, @@ -536,6 +544,21 @@ mod tests { assert_eq!(login_base.org_name, Some("custom-org".into())); } + #[test] + fn current_switch_auth_context_prefers_profile_over_stale_org() { + let mut base = base_args(None, Some("project")); + let current_cfg = config::Config { + profile: Some("BT Staging".to_string()), + org: Some("braintrustdata.com".to_string()), + ..Default::default() + }; + + apply_current_switch_auth_context(&mut base, ¤t_cfg); + + assert_eq!(base.profile.as_deref(), Some("BT Staging")); + assert_eq!(base.org_name, None); + } + #[test] fn apply_switch_config_sets_project_id_with_project_name_and_org() { let mut cfg = config::Config::default();