From bbb3c158f9dc13eafbc4cc4350c74095adccb849 Mon Sep 17 00:00:00 2001 From: Shayna Chambless Date: Tue, 21 Jul 2026 14:48:36 -0700 Subject: [PATCH 1/4] fix url --- src/config.rs | 8 +++++--- src/utils/auth_token/org_auth_token.rs | 13 +++++++++++++ src/utils/auth_token/test.rs | 4 ++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/config.rs b/src/config.rs index a12b6cf57b..b3546d07b8 100644 --- a/src/config.rs +++ b/src/config.rs @@ -150,7 +150,7 @@ impl Config { }; let token_url = token_data .as_ref() - .map(|data| data.url.as_str()) + .map(|data| data.base_url()) .unwrap_or_default(); let base_url = if token_url.is_empty() { auth_and_url.url.unwrap_or_else(|| DEFAULT_URL.to_owned()) @@ -282,7 +282,7 @@ impl Config { Some(Auth::Token(ref val)) => { self.cached_token_data = val.payload().cloned(); - if let Some(token_url) = self.cached_token_data.as_ref().map(|td| td.url.as_str()) { + if let Some(token_url) = self.cached_token_data.as_ref().map(|td| td.base_url()) { self.cached_base_url = token_url.to_owned(); } @@ -719,7 +719,9 @@ impl AuthAndUrl { /// Returns whether a token is self-contained because it has a nonempty embedded URL. fn token_has_embedded_url(token: &AuthToken) -> bool { - token.payload().is_some_and(|data| !data.url.is_empty()) + token + .payload() + .is_some_and(|data| !data.base_url().is_empty()) } /// Determines which inherited value must be removed before applying another source. diff --git a/src/utils/auth_token/org_auth_token.rs b/src/utils/auth_token/org_auth_token.rs index c464a2d0cf..97b8085a82 100644 --- a/src/utils/auth_token/org_auth_token.rs +++ b/src/utils/auth_token/org_auth_token.rs @@ -19,6 +19,19 @@ pub struct AuthTokenPayload { // URL may be missing from some old auth tokens, see getsentry/sentry#57123 #[serde(deserialize_with = "url_deserializer")] pub url: String, + + #[serde(default, deserialize_with = "url_deserializer")] + pub region_url: String, +} + +impl AuthTokenPayload { + pub fn base_url(&self) -> &str { + if self.region_url.is_empty() { + &self.url + } else { + &self.region_url + } + } } /// Deserializes a URL from a string, returning an empty string if the URL is missing or null. diff --git a/src/utils/auth_token/test.rs b/src/utils/auth_token/test.rs index a25568b150..d4bf1296fa 100644 --- a/src/utils/auth_token/test.rs +++ b/src/utils/auth_token/test.rs @@ -21,6 +21,8 @@ fn test_valid_org_auth_token() { let payload = token.payload().unwrap(); assert_eq!(payload.org, "sentry"); assert_eq!(payload.url, "http://localhost:8000"); + assert_eq!(payload.region_url, "http://localhost:8000"); + assert_eq!(payload.base_url(), "http://localhost:8000"); assert_eq!(good_token, token.raw().expose_secret().clone()); @@ -43,6 +45,8 @@ fn test_valid_org_auth_token_missing_url() { let payload = token.payload().unwrap(); assert_eq!(payload.org, "sentry"); assert!(payload.url.is_empty()); + assert_eq!(payload.region_url, "http://localhost:8000"); + assert_eq!(payload.base_url(), "http://localhost:8000"); assert_eq!(good_token, token.raw().expose_secret().clone()); From e230445c092ecbc76fb5a4bad3f11238c5b50ee5 Mon Sep 17 00:00:00 2001 From: Shayna Chambless Date: Tue, 21 Jul 2026 14:53:54 -0700 Subject: [PATCH 2/4] changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d297ab90d3..2c5a97c773 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Fixes + +- (auth) Use an org auth token's embedded `region_url` as the API base URL so uploads from orgs with non-default (e.g. EU) data residency reach the correct region instead of failing with `Invalid org token`. Previously only the token's `url` (always the primary US URL) was honored, and `SENTRY_URL`/`--url` overrides were ignored + ## 3.6.2 ### Fixes From f5530690069bcffe5f1e3595a80104c0ddd34a68 Mon Sep 17 00:00:00 2001 From: Shayna Chambless Date: Thu, 23 Jul 2026 09:32:10 -0700 Subject: [PATCH 3/4] failing ci checks --- .../_cases/org_tokens/url-mismatch-empty-token.trycmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration/_cases/org_tokens/url-mismatch-empty-token.trycmd b/tests/integration/_cases/org_tokens/url-mismatch-empty-token.trycmd index db83846b6c..961a68c8ed 100644 --- a/tests/integration/_cases/org_tokens/url-mismatch-empty-token.trycmd +++ b/tests/integration/_cases/org_tokens/url-mismatch-empty-token.trycmd @@ -1,8 +1,8 @@ -This auth token has an empty URL. We expect the --url argument to take precedence here +This auth token has an empty URL but a set region URL. The region URL is used as the base URL and takes precedence over the --url argument. ``` $ sentry-cli --auth-token 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 --url https://sentry.example.com info ? failed -Sentry Server: https://sentry.example.com +[..]WARN[..] Using http://localhost:8000 (embedded in token) rather than manually-configured URL https://sentry.example.com. To use https://sentry.example.com, please provide an auth token for https://sentry.example.com. ... ``` From 9d0f5e4cbc3fda94ac2d745af69e04914579fcb2 Mon Sep 17 00:00:00 2001 From: Shayna Chambless Date: Thu, 23 Jul 2026 11:01:38 -0700 Subject: [PATCH 4/4] changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c5a97c773..70d8dfdada 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ### Fixes -- (auth) Use an org auth token's embedded `region_url` as the API base URL so uploads from orgs with non-default (e.g. EU) data residency reach the correct region instead of failing with `Invalid org token`. Previously only the token's `url` (always the primary US URL) was honored, and `SENTRY_URL`/`--url` overrides were ignored +- (auth) Use an org auth token's embedded `region_url` as the API base URL so uploads from orgs with non-default (e.g. EU) data residency reach the correct region instead of failing with `Invalid org token`. Previously only the token's `url` (always the primary US URL) was honored, and `SENTRY_URL`/`--url` overrides were ignored ([#3377](https://github.com/getsentry/sentry-cli/pull/3377)) ## 3.6.2