feat(args): parse Sentry web URLs as CLI arguments#252
Conversation
Semver Impact of This PR🟡 Minor (new features) 📋 Changelog PreviewThis is how your changes will appear in the changelog. New Features ✨Build
Other
Bug Fixes 🐛Telemetry
Other
Internal Changes 🔧
🤖 This preview updates automatically when you update the PR. |
Codecov Results 📊✅ Patch coverage is 89.52%. Project has 4103 uncovered lines. Files with missing lines (71)
Coverage diff@@ Coverage Diff @@
## main #PR +/-##
==========================================
+ Coverage 68.53% 68.74% +0.21%
==========================================
Files 109 110 +1
Lines 13010 13124 +114
Branches 0 0 —
==========================================
+ Hits 8916 9021 +105
- Misses 4094 4103 +9
- Partials 0 0 —Generated by Codecov Action |
src/lib/sentry-url-parser.ts
Outdated
| if (process.env.SENTRY_URL) { | ||
| return; | ||
| } |
There was a problem hiding this comment.
I'd say the parsed URL should take precedence over any previously set env variable.
Users can now paste Sentry web URLs directly as CLI arguments instead
of manually extracting org/project/issue IDs. Supports both SaaS
(sentry.io) and self-hosted instances.
URL patterns supported:
- /organizations/{org}/issues/{id}/ (issue view/explain/plan)
- /organizations/{org}/issues/{id}/events/{eventId}/ (event view)
- /settings/{org}/projects/{project}/ (project commands)
- /organizations/{org}/traces/{traceId}/ (trace commands)
- /organizations/{org}/ (org-scoped commands)
For self-hosted URLs, automatically sets SENTRY_URL so that API calls,
OAuth device flow, and token refresh target the correct instance.
Also fixes frozen module-level constants in oauth.ts and sentry-client.ts
that captured SENTRY_URL at import time, preventing dynamic URL detection
from working.
- Event URLs no longer trigger OrgAll → ContextError; instead they auto-detect org/project after SENTRY_URL is set (HIGH) - SaaS URLs now clear stale SENTRY_URL so API calls use default routing instead of a leftover self-hosted value (MEDIUM) - Non-issue URLs (traces, project settings) in parseIssueArg now throw ValidationError instead of falling through to garbage slash-based parsing (LOW)
process.env.SENTRY_URL = undefined sets the string "undefined" in Node.js (Bun handles it correctly). Use delete with a biome-ignore to truly unset the env var when a SaaS URL is detected.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
Instead of discarding the org extracted from event URLs, pass it as OrgAll target and handle OrgAll in viewCommand by falling through to auto-detect. This keeps the org context available while resolving the project via DSN detection or config defaults.
| // Org-only (e.g., from event URL that has no project slug). | ||
| // Fall through to auto-detect — SENTRY_URL is already set for | ||
| // self-hosted, and auto-detect will resolve the project from | ||
| // DSN, config defaults, or directory name inference. | ||
| // falls through | ||
| case ProjectSpecificationType.AutoDetect: |
There was a problem hiding this comment.
Bug: The event view command discards the organization parsed from an event URL, causing it to potentially fetch the event from the wrong organization based on auto-detection.
Severity: MEDIUM
Suggested Fix
In the ProjectSpecificationType.OrgAll case within src/commands/event/view.ts, pass the parsed organization to the resolveOrgAndProject function. The call should be updated to await resolveOrgAndProject({ org: parsed.org, cwd, usageHint: USAGE_HINT }) to ensure the project lookup is constrained to the correct organization.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: src/commands/event/view.ts#L215-L220
Potential issue: When the `event view` command is used with a full event URL, the
organization is correctly parsed from the URL but is subsequently discarded. The
`resolveOrgAndProject` function is then called without the `org` parameter. This
triggers an auto-detection mechanism that may resolve to a different organization based
on local configuration or environment variables. As a result, the command may attempt to
fetch the event from the wrong organization, leading to a failure to find the specified
event.
Summary
sentry issue view https://sentry.example.com/organizations/my-org/issues/32886/?project=2) instead of manually extracting org/project/issue IDsSENTRY_URLfor the sessionoauth.tsandsentry-client.tsthat prevented dynamic URL detection from workingURL Patterns Supported
/organizations/{org}/issues/{id}/issue view,issue explain,issue plan/organizations/{org}/issues/{id}/events/{eventId}/event view/settings/{org}/projects/{project}/project view,project list/organizations/{org}/traces/{traceId}/trace view/organizations/{org}/Changes
New Files
src/lib/sentry-url-parser.ts— Pure URL parser (parseSentryUrl) + self-hosted env config (applySentryUrlContext)test/lib/sentry-url-parser.test.ts— 30 unit tests covering all URL patterns, edge cases, and env var behaviortest/lib/sentry-url-parser.property.test.ts— Round-trip property tests verifying URLs built bysentry-urls.tscan be parsed backModified Files
src/lib/arg-parsing.ts— URL pre-parsing inparseIssueArg()andparseOrgProjectArg()src/commands/event/view.ts— URL handling inparsePositionalArgs()for event URLssrc/lib/oauth.ts— Replaced frozenconst SENTRY_URLwith lazygetSentryUrl()functionsrc/lib/sentry-client.ts— Removed frozenconst CONTROL_SILO_URL, madegetControlSiloUrl()read env var lazilyTest Updates
test/lib/arg-parsing.test.ts— Added URL integration tests for both parserstest/commands/event/view.test.ts— Added event URL handling testsFixes
Resolves CLI-66 (self-hosted users get confusing errors when pasting URLs)