Skip to content

feat(api): Add project ID-or-slug parser#117445

Merged
gricha merged 1 commit into
masterfrom
feat/project-id-or-slug-foundation
Jun 12, 2026
Merged

feat(api): Add project ID-or-slug parser#117445
gricha merged 1 commit into
masterfrom
feat/project-id-or-slug-foundation

Conversation

@gricha

@gricha gricha commented Jun 11, 2026

Copy link
Copy Markdown
Member

Add a shared project ID-or-slug parser and DRF field for endpoints that explicitly opt in to accepting either identifier. Existing ProjectField behavior stays slug-only by default, while id_allowed=True can now resolve project IDs or slugs within the current organization and permission context.

This is the foundation PR for the project slug API split. It only introduces the helper, serializer support, and focused tests; endpoint resolver behavior lands in the stacked follow-up PR #117446.

Add a shared project ID-or-slug field and parser for endpoints that opt in to accepting either identifier. Keep existing ProjectField behavior slug-only by default and add tests for parser, serializer, and numeric slug invariants.

Co-Authored-By: OpenAI GPT-5.5 <noreply@openai.com>
@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label Jun 11, 2026
@gricha gricha marked this pull request as ready for review June 11, 2026 19:38
@gricha gricha requested a review from a team as a code owner June 11, 2026 19:38
Comment on lines 39 to +43
else:
project = Project.objects.get(organization=self.context["organization"], slug=data)
project_slug = self._validate_slug(data)
project = Project.objects.get(
organization=self.context["organization"], slug=project_slug
)

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.

Bug: An invalid project slug raises a generic validation error instead of the intended "Invalid project" error because the specific ValidationError is not caught.
Severity: LOW

Suggested Fix

Modify the except block in ProjectField.to_internal_value to also catch serializers.ValidationError. Inside the handler, raise a new serializers.ValidationError with the intended 'Invalid project' message to ensure consistent error reporting for all invalid project identifiers.

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/sentry/api/serializers/rest_framework/project.py#L39-L43

Potential issue: The `try...except` block in `ProjectField.to_internal_value` is
intended to catch lookup failures and return a `ValidationError` with the message
"Invalid project". However, when an invalid slug format is used (e.g., containing a
space), the underlying `ProjectIdOrSlugField` raises a `serializers.ValidationError`
before the database lookup occurs. This validation error is not caught by the `except
Project.DoesNotExist` handler, causing a generic slug format error to be returned to the
user instead of the intended, more specific "Invalid project" message.

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

@gricha gricha merged commit ca6f4c4 into master Jun 12, 2026
67 checks passed
@gricha gricha deleted the feat/project-id-or-slug-foundation branch June 12, 2026 01:01
gricha added a commit that referenced this pull request Jun 12, 2026
Organization project resolution now accepts project IDs, slugs, or mixed
ID-and-slug values through the canonical `project` query parameter.
Permission checks still run through `get_projects()`, legacy
`projectSlug` filters keep existing runtime precedence, existing
`projectSlug` OpenAPI fields remain available, empty project filters are
treated as absent, and stats endpoints preserve permission-scoped
project materialization when grouping by project.

This PR is stacked on #117445 and intentionally stops at the shared
organization resolver, generic API docs, stats, and combined-alert
callers. Product-specific endpoint opt-ins are split into separate draft
PRs against this resolver branch.

---------

Co-authored-by: OpenAI GPT-5.5 <noreply@openai.com>
Co-authored-by: OpenCode <noreply@opencode.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants