Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/lib/arg-parsing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -369,9 +369,15 @@
projectSlug: string;
/** True if project slug was normalized */
normalized?: boolean;
/**
* Organization slug to scope the search to, when the caller provided
* one (e.g. "org/My Project"). When unset the search spans all
* accessible organizations.
*/
org?: string;
/**
* Pre-normalization input when {@link normalized} is `true`.
* Used by the resolution layer to produce user-friendly messages

Check failure on line 380 in src/lib/arg-parsing.ts

View check run for this annotation

@sentry/warden / warden: find-bugs

`project-search` branch in `resolveTargetsFromParsedArg` ignores `parsed.org`/display-name flag, leaving `sentry issue list sentry/My Project` broken

The fix for display-name projects with spaces was only wired into `resolveOrgProjectTarget` (trace/log/event commands). `resolveTargetsFromParsedArg` — the canonical resolver for project-scoped list commands like `sentry issue list` and `alert issue list` — has a separate `project-search` branch that calls `findProjectsBySlug(parsed.projectSlug)` unconditionally. It never inspects `parsed.originalSlug` (the display-name marker) or `parsed.org`. As a result, an input like `sentry/My Project` (or bare `My Project`) emitted as `{type:'project-search', projectSlug:'My Project', originalSlug:'My Project', org:'sentry'}` causes per-org `getProject(org, 'My Project')` lookups that all 404 (slug never contains spaces), then `findProjectsByPattern` (slug word-boundary match) also fails to match a display name with spaces, so the command throws a `ResolutionError: Project 'My Project' not found` — defeating the PR's stated goal for these commands.
* that reference what the user actually typed rather than the
* intermediate normalized form.
*/
Expand Down Expand Up @@ -536,6 +542,18 @@

// "sentry/cli" → explicit org and project
rejectAtSelector(rawProject, "project slug");
if (looksLikeDisplayName(rawProject)) {
// Spaces → display name, not a slug. Skip slug validation and let the
// resolution layer do a fuzzy name-based search (mirrors the bare-slug
// and leading-slash paths). Prevents a hard ValidationError when callers
// pass a project display name in "org/project" form (CLI-1RA).
return {
type: "project-search",
projectSlug: rawProject,
originalSlug: rawProject,
org: no.slug,
};
}
const np = normalizeSlug(rawProject);
validateResourceId(np.slug, "project slug");
const normalized = no.normalized || np.normalized;
Expand Down
9 changes: 8 additions & 1 deletion src/lib/resolve-target.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1640,10 +1640,17 @@ export async function resolveOrgProjectTarget(
case "project-search": {
const displaySlug = parsed.originalSlug ?? parsed.projectSlug;
const isDisplayName = parsed.originalSlug !== undefined;
const { projects, orgs } = isDisplayName
const { projects, orgs: foundOrgs } = isDisplayName
? { projects: [], orgs: await listOrganizations() }
: await findProjectsBySlug(parsed.projectSlug);

Comment on lines +1643 to 1646

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Bug: The resolveTargetsFromParsedArg function doesn't handle project display names (e.g., "My Project") when an organization is specified, causing commands like sentry issue list to fail.
Severity: MEDIUM

Suggested Fix

The logic for handling display names from resolveOrgProjectTarget should be mirrored in the project-search case within resolveTargetsFromParsedArg. Specifically, it should check if the project identifier is a display name and, if so, skip the findProjectsBySlug call and proceed directly to the fuzzy matching logic, ensuring the search is correctly scoped to the provided 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/lib/resolve-target.ts#L1643-L1646

Potential issue: The `resolveTargetsFromParsedArg` function, used by commands like
`sentry issue list`, does not correctly handle project searches that use a display name
containing spaces (e.g., `sentry/"My Project"`). The code enters the `project-search`
case and calls `findProjectsBySlug` with the display name, which is not a valid slug and
causes the search to fail. The logic to handle display names by skipping
`findProjectsBySlug` and performing fuzzy matching was implemented in
`resolveOrgProjectTarget` but was missed in `resolveTargetsFromParsedArg`, leading to
inconsistent behavior and command failure for this use case.

Did we get this right? 👍 / 👎 to inform future reviews.

// When the caller provided an org (e.g. "org/My Project"), scope the
// display-name search to that org instead of all accessible orgs.
const orgs =
isDisplayName && parsed.org !== undefined
? foundOrgs.filter((o) => o.slug === parsed.org)
: foundOrgs;

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.

Org scope ignored in fuzzy search

Medium Severity

project-search now carries optional org for org/<display name>, and only resolveOrgProjectTarget filters organizations before fuzzy matching. resolveProjectBySlug, handleProjectSearch, and similar paths still search all accessible orgs, so an explicit org prefix may resolve to the wrong project.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit b7d99fb. Configure here.


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.

Issue list ignores display names

High Severity

Parsing now emits project-search with originalSlug for org/<display name>, but resolveTargetsFromParsedArg still only calls findProjectsBySlug and slug-pattern fallbacks. It never uses display-name triage, so sentry issue list (and similar list commands) keep failing after the parse fix.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit b7d99fb. Configure here.

if (projects.length === 0) {
const outcome = await triageProjectNotFound(
parsed.projectSlug,
Expand Down
Loading