Skip to content

fix(init): recover gracefully when org listing returns 403#963

Merged
betegon merged 1 commit into
mainfrom
fix/init-forbidden-org-list
May 13, 2026
Merged

fix(init): recover gracefully when org listing returns 403#963
betegon merged 1 commit into
mainfrom
fix/init-forbidden-org-list

Conversation

@betegon
Copy link
Copy Markdown
Member

@betegon betegon commented May 13, 2026

When a user runs `sentry init` without specifying an org, the CLI calls `listOrganizations()` to show a picker. If the auth token lacks `org:read` scope — common with limited `SENTRY_AUTH_TOKEN` env tokens — that call 403s. The exception had no handler in `resolveOrgSlug()`, so it propagated to `withPreflightHandling()` which logged only `error.message` and killed the wizard entirely, with no indication of how to proceed.

Before:

✗ Failed to list organizations: 403 Forbidden
✗ Setup failed.

After (env-var token path shown; OAuth path substitutes "Re-authenticate with: sentry auth login"):

✗ Could not list organizations (403 Forbidden).
  Your SENTRY_AUTH_TOKEN token may lack the required scope for this operation.
  Check token scopes at: https://sentry.io/settings/auth-tokens/

  Specify the org on the command line:  sentry init <org-slug>/
  Or set an environment variable:       SENTRY_ORG=<org-slug> sentry init
✗ Setup failed.

The fix catches `ApiError(403)` in `resolveOrgSlug()` and returns a structured `{ ok: false }` error instead of throwing. The message surfaces `error.detail` (already enriched by `enrich403Detail()` with token-scope guidance) plus two actionable recovery hints. Non-403 errors are re-thrown unchanged. The `{ ok: false }` return flows through the existing `ensureOrg()` → `withPreflightHandling()` chain with no other code changes needed.

Ref: sentry issue 7466435851

Test plan

  • Set `SENTRY_AUTH_TOKEN` to a token with no `org:read` scope (e.g. only `project:write`)
  • Run `sentry init` with no org argument
  • Should print the token-scope hint + the two recovery suggestions, then exit cleanly
  • Confirm `sentry init /` still works end-to-end with the same limited token

When the CLI can't resolve an org from the codebase (no DSN, no
SENTRY_ORG env var), it calls listOrganizations() to let the user
pick one. If the auth token lacks org:read scope, that call 403s and
the exception propagates to withPreflightHandling(), which logs only
error.message ("Failed to list organizations: 403 Forbidden") and
kills the wizard — with no hint on how to proceed.

Fix: catch the ApiError(403) in resolveOrgSlug() and return a
structured { ok: false } result instead of throwing. The message
surfaces error.detail (already enriched by enrich403Detail() with
token-scope guidance) plus two actionable recovery suggestions:
  sentry init <org-slug>/
  SENTRY_ORG=<org-slug> sentry init

Non-403 errors are re-thrown unchanged. Fixes sentry issue #7466435851.
@github-actions
Copy link
Copy Markdown
Contributor

PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://cli.sentry.dev/_preview/pr-963/

Built to branch gh-pages at 2026-05-13 14:26 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@github-actions
Copy link
Copy Markdown
Contributor

Codecov Results 📊

6959 passed | Total: 6959 | Pass Rate: 100% | Execution Time: 0ms

📊 Comparison with Base Branch

Metric Change
Total Tests
Passed Tests
Failed Tests
Skipped Tests

✨ No test changes detected

All tests are passing successfully.

❌ Patch coverage is 27.78%. Project has 14165 uncovered lines.
✅ Project coverage is 77%. Comparing base (base) to head (head).

Files with missing lines (1)
File Patch % Lines
src/lib/init/preflight.ts 27.78% ⚠️ 13 Missing
Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
+ Coverage    76.99%    77.00%    +0.01%
==========================================
  Files          320       320         —
  Lines        61577     61574        -3
  Branches         0         0         —
==========================================
+ Hits         47406     47409        +3
- Misses       14171     14165        -6
- Partials         0         0         —

Generated by Codecov Action

@betegon betegon marked this pull request as ready for review May 13, 2026 14:40
@betegon betegon merged commit b04a05a into main May 13, 2026
27 checks passed
@betegon betegon deleted the fix/init-forbidden-org-list branch May 13, 2026 16:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant