fix(resolve): use an org slug only when no project matches - #1622
Conversation
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>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
Co-authored-by: Cursor <cursoragent@cursor.com>
|
Yes, we should standardise this behaviour as it was always meant to be |
Co-authored-by: Cursor <cursoragent@cursor.com>
|
Yes — 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 I've also applied that fallback to the |
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…lback Co-authored-by: Cursor <cursoragent@cursor.com> # Conflicts: # packages/cli/test/commands/event/view.test.ts
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.
Reviewed by Cursor Bugbot for commit b787657. Configure here.
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
## 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>

Summary
A bare target was resolved differently depending on the command and cache state.
sentry issue list acmeandsentry explore acmecould fail whenacmewas 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:
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*, orresolveOrgOnly*) instead of implementing project/org lookup itself. This also covers the alert-list--webshortcuts and trace/log target paths that previously bypassed the shared list dispatcher.sentry initintentionally 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 skippedpnpm run lintpnpm exec tsc --noEmit<org>/and<org>/<project>forms bypass bare-target fallback--web, dashboard, trace/log, replay, feedback, explore, and init paths use their capability policy