Skip to content

fix(resolve): use an org slug only when no project matches - #1622

Merged
betegon merged 9 commits into
mainfrom
fix/bare-slug-org-fallback
Sep 28, 2026
Merged

betegon merged 9 commits into
mainfrom
fix/bare-slug-org-fallback

Conversation

@betegon

@betegon betegon commented Sep 22, 2026 •

Copy link
Copy Markdown
Member

Summary

A bare target was resolved differently depending on the command and cache state. sentry issue list acme and sentry explore acme could fail when acme was an organization, while a warm cache could make the organization win even when a project had the same slug.

Target resolution now has one shared order:

  1. exact project match(es)
  2. exact organization match
  3. fuzzy project recovery
  4. not found

The slash forms stay explicit: <org>/ selects the organization and <org>/<project> selects that project. Without a slash, a project always wins when a project and organization share the same slug. Commands that support organization scope fall back to the organization only after the project search misses; project-bound commands keep requiring a project and return an actionable error for an organization match.

The command layer now chooses an explicit capability helper (resolveProjectBound*, resolveOrgOptional*, or resolveOrgOnly*) instead of implementing project/org lookup itself. This also covers the alert-list --web shortcuts and trace/log target paths that previously bypassed the shared list dispatcher. sentry init intentionally disables fuzzy recovery and keeps its special true-miss behavior of creating a new project. Issue-ID recovery remains a documented non-target-resolution exception.

Test plan

  • TZ=UTC pnpm run test:unit — 464 files, 9,963 passed, 14 skipped
  • pnpm run lint
  • pnpm exec tsc --noEmit
  • Same project and organization slug: project wins
  • No project and exact organization slug: org-capable commands use the organization
  • Project-bound commands still reject an organization-only target
  • Explicit <org>/ and <org>/<project> forms bypass bare-target fallback
  • Alert --web, dashboard, trace/log, replay, feedback, explore, and init paths use their capability policy

A bare name searches projects first. The organization is used when that
search misses and the slug is an org, including with a cold cache.
A trailing slash stays the explicit organization form, so a project
that shares the org's name still wins.

Co-authored-by: Cursor <cursoragent@cursor.com>
@vercel

vercel Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
cli Ready Ready Preview Sep 28, 2026 10:06am UTC
1 Skipped Deployment
Project Deployment Actions Updated
sentry-local Skipped Skipped Sep 28, 2026 10:06am UTC

Request Review

Co-authored-by: Cursor <cursoragent@cursor.com>
@BYK

BYK commented Sep 22, 2026 •

Copy link
Copy Markdown
Member

Yes, we should standardise this behaviour as it was always meant to be <project>, <org>/ or <org>/project

Co-authored-by: Cursor <cursoragent@cursor.com>
@vercel
vercel Bot temporarily deployed to Preview – sentry-local September 22, 2026 16:23 Inactive
@betegon

betegon commented Sep 22, 2026

Copy link
Copy Markdown
Member Author

Yes — <project>, <org>/, and <org>/<project> remain the canonical forms.

The additional fallback here is deliberately project-first: when someone passes a bare value, we search for a project with that slug first. Only if no project matches and the value exactly matches an accessible organization do we use it as the organization (equivalent to <org>/) and emit a warning. If a project and organization share the same slug, the project wins.

I've also applied that fallback to the --web paths for issue and metric alert lists, which previously bypassed the shared resolver, so the behavior is now consistent there too.

@betegon
betegon marked this pull request as ready for review September 22, 2026 16:28
@github-actions github-actions Bot added the risk: medium PR risk score: medium label Sep 22, 2026
Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread packages/cli/src/lib/resolve-target.ts Outdated
Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread packages/cli/src/lib/resolve-target.ts
Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread packages/cli/src/lib/org-list.ts
…lback

Co-authored-by: Cursor <cursoragent@cursor.com>

# Conflicts:
#	packages/cli/test/commands/event/view.test.ts

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b787657. Configure here.

Comment thread packages/cli/src/lib/resolve-target.ts
Co-authored-by: Cursor <cursoragent@cursor.com>
@vercel
vercel Bot temporarily deployed to Preview – sentry-local September 28, 2026 09:30 Inactive
@github-actions github-actions Bot added risk: medium PR risk score: medium and removed risk: medium PR risk score: medium labels Sep 28, 2026
Co-authored-by: Cursor <cursoragent@cursor.com>
@vercel
vercel Bot temporarily deployed to Preview – sentry-local September 28, 2026 10:06 Inactive
@github-actions github-actions Bot added risk: medium PR risk score: medium and removed risk: medium PR risk score: medium labels Sep 28, 2026
@betegon
betegon merged commit a718ef9 into main Sep 28, 2026
37 of 39 checks passed
@betegon
betegon deleted the fix/bare-slug-org-fallback branch September 28, 2026 11:34
betegon added a commit that referenced this pull request Sep 28, 2026
## Summary

Follow-up to #1622. CLI commands should resolve project/org targets
through the capability helpers in `resolve-target.ts`; calling
`findProjectsBySlug()` or the old miss classifier directly lets
command-specific precedence drift.

This adds a Biome Grit rule for `src/commands/**` that rejects direct
low-level target lookup, including namespace-style calls.
`commands/issue/utils.ts` is explicitly excluded because its project
lookup is part of issue-ID resolution, not CLI target parsing.

The command-layer boundary is also documented in `AGENTS.md` so the
diagnostic points contributors to the intended architecture.

## Test plan

- [x] `pnpm run lint`
- [x] `pnpm exec tsc --noEmit`
- [x] Temporary command fixture calling `findProjectsBySlug()` produces
the new plugin diagnostic
- [x] Existing intentional lookup in `commands/issue/utils.ts` remains
accepted

Made with [Cursor](https://cursor.com)

Co-authored-by: Cursor <cursoragent@cursor.com>

This branch was successfully deployed

1 active and 1 inactive deployments
Preview – cli — 05156a5a Deployed Sep 28, 2026 by vercel[bot]
Preview – sentry-local — 05156a5a Deployed Sep 28, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk: medium PR risk score: medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants