Repository navigation
ref(cli): Move API calls with generated operations onto @sentry/api - #2073
Merged
Merged
Conversation
Bump @sentry/api to 1.44.0 and move the apiRequest* call sites that have a matching generated operation onto it: alert rule delete, chunk upload options and assemble (debug files, sourcemaps, dart symbols, proguard), AI conversation detail, short ID resolve, preprod install details and snapshot latest base, release commit refs, replay detail, trace meta, and the transactions/spans event pages. Add validateResponse/unwrapValidatedResult so call sites that already check responses with a Zod schema keep doing that on SDK results. This is step 1 of moving the CLI onto generated operations. The remaining sites are blocked on missing public schema entries or type mismatches and stay on the helpers for now. Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This was referenced Nov 7, 2026
Merged
BYK
added a commit
to getsentry/sentry
that referenced
this pull request
Nov 7, 2026
The OpenAPI schema for `PUT /organizations/{org}/issues/{issue_id}/`
(`updateOrganizationIssue`) and `PUT /organizations/{org}/issues/`
(`updateOrganizationIssues`) listed every `GroupValidator` field, and
every `statusDetails` field, as required. The endpoints always validate
with `partial=True` (`validate_request` in
`api/helpers/group_index/update.py`), so a request only sends the fields
it changes, for example `{"status": "resolved"}`.
This marks those fields `required=False`. Validation doesn't change,
because `partial=True` already skipped the required check. Only the two
operations above change in the generated schema. Their request body
schemas lose the `required` lists, and the body itself is no longer
marked required.
The Sentry CLI needs this to move its issue update calls onto the
generated `@sentry/api` operations (getsentry/toolkit#2073). Today the
generated body type makes every field mandatory, so a partial update
doesn't typecheck.
Checked locally with `make build-api-docs`, `pnpm run
validate-api-examples`, `tests/apidocs`,
`tests/sentry/issues/endpoints/test_group_details.py`, `GroupUpdateTest`
in `test_organization_group_index.py`,
`tests/sentry/api/helpers/test_group_index.py`, prek and mypy. Under
xdist, three snuba-backed `GroupUpdateTest` cases failed:
`test_resolve_with_integration`, `test_snooze_user_count` and
`test_bulk_resolve`. Run serially, they pass on this branch and on
master.
<!-- junior-request-attribution:start -->
via @BYK.
<!-- junior-request-attribution:end -->
<!-- junior-session-footer:start -->
<!-- junior-conversation-id:agent%3A80220b9d4c297e2a971f05dcb03af515 -->
--
[View
Session](https://junior-prod.sentry.dev/conversations/agent%3A80220b9d4c297e2a971f05dcb03af515)
[[Sentry]](https://sentry.sentry.io/explore/conversations/agent%3A80220b9d4c297e2a971f05dcb03af515/?project=4510944073809921)
<!-- junior-session-footer:end -->
Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
Co-authored-by: BYK <126780+BYK@users.noreply.github.com>
BYK
added a commit
to getsentry/sentry
that referenced
this pull request
Nov 7, 2026
…estamp (#130349) Three query parameters on public Explore endpoints were documented differently from what the code accepts: - **`yAxis`** on `listOrganizationEventsTimeseries` was a single string. The endpoint reads `request.GET.getlist("yAxis")` and returns one timeseries per aggregate, so it's now an array (repeated `?yAxis=count()&yAxis=p95(span.duration)`). - **`interval`** (`VisibilityParams.INTERVAL`, used by `listOrganizationEventsTimeseries` and `listOrganizationEventsDropped`) was an integer. `get_rollup_from_request` parses it with `parse_stats_period`, which also takes a unit suffix such as `5m` or `1h`. It's now `anyOf: [integer, string matching ^\d+[smhdw]?$]`, so callers that pass a number keep working. - **`timestamp`** on `getOrganizationTrace` and `getOrganizationTraceMeta` wasn't listed. Both endpoints pass it to `update_snuba_params_with_timestamp`, which accepts ISO 8601 or Unix seconds and narrows the query window. I added it as `TraceParams.TIMESTAMP`. Only those four operations change in the generated schema. There's no runtime change. The Sentry CLI needs these to move its timeseries and trace calls onto the generated `@sentry/api` operations (getsentry/toolkit#2073). Right now the generated types reject repeated `yAxis`, `interval=1h` and `timestamp`. One thing to note for SDK consumers: the generated `yAxis` type changes from `string` to `string[]`. Checked locally with `make build-api-docs`, `pnpm run validate-api-examples`, `tests/apidocs`, prek and mypy. I also ran `tests/snuba/api/endpoints/test_organization_trace_meta.py` and `test_organization_events_timeseries.py::test_simple`. Under xdist those snuba tests miss rows from shared state, but run serially they pass. <!-- junior-request-attribution:start --> via @BYK. <!-- junior-request-attribution:end --> <!-- junior-session-footer:start --> <!-- junior-conversation-id:agent%3A80220b9d4c297e2a971f05dcb03af515 --> -- [View Session](https://junior-prod.sentry.dev/conversations/agent%3A80220b9d4c297e2a971f05dcb03af515) [[Sentry]](https://sentry.sentry.io/explore/conversations/agent%3A80220b9d4c297e2a971f05dcb03af515/?project=4510944073809921) <!-- junior-session-footer:end --> Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com> Co-authored-by: BYK <126780+BYK@users.noreply.github.com>
BYK
added a commit
to getsentry/sentry
that referenced
this pull request
Nov 7, 2026
…0350) `GET /organizations/{org}/agents/conversations/` (`listOrganizationAIConversations`) accepts a `sort` query param. `OrganizationAIConversationsSerializer` validates it against `AI_CONVERSATIONS_FIELDS`, and it defaults to `-conversation.age`, but the OpenAPI docs didn't list it. This adds the parameter with an enum of the canonical fields, each with an optional `-` prefix. Only this operation changes in the generated schema, and there's no runtime change. The enum comes from a new `AI_CONVERSATIONS_SORT_FIELDS` tuple. It takes the keys of `AI_CONVERSATIONS_FIELDS` before the legacy spellings are added, so `messages`, the bare field names and the function aliases stay accepted but undocumented. The Sentry CLI's `agent-conversation list --sort` needs this to move onto the generated `@sentry/api` operation (getsentry/toolkit#2073). The generated query type has no `sort` today. Checked locally with `make build-api-docs`, `pnpm run validate-api-examples`, `tests/sentry/api/endpoints/test_organization_ai_conversations.py`, `tests/apidocs`, prek and mypy. <!-- junior-request-attribution:start --> via @BYK. <!-- junior-request-attribution:end --> <!-- junior-session-footer:start --> <!-- junior-conversation-id:agent%3A80220b9d4c297e2a971f05dcb03af515 --> -- [View Session](https://junior-prod.sentry.dev/conversations/agent%3A80220b9d4c297e2a971f05dcb03af515) [[Sentry]](https://sentry.sentry.io/explore/conversations/agent%3A80220b9d4c297e2a971f05dcb03af515/?project=4510944073809921) <!-- junior-session-footer:end --> Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com> Co-authored-by: BYK <126780+BYK@users.noreply.github.com>
BYK
enabled stacked auto-merge (squash)
November 7, 2026 02:11
BYK
added a commit
that referenced
this pull request
Nov 7, 2026
Stacked on #2073. That PR moves the CLI onto the generated `@sentry/api` operations. This one fixes the cases where the CLI, not the API docs, was wrong. The full list is in getsentry/sentry#130351. Where the 1.44.0 operation now matches, the call moves onto it here too. Each fix was checked against the getsentry/sentry endpoint code. ### Moved onto generated operations | Area | Fix | Operation | | --- | --- | --- | | `alert issues list/view` | Filter workflows by `project` (the endpoint ignores `projectSlug`) and send `id` as a number | `listOrganizationWorkflows` (×2) | | `code-mappings upload` | Send the bulk body in snake_case: `default_branch`, `stack_root`, `source_root` | `bulkUpsertOrganizationCodeMappings` | | `explore`, `dashboard view` tables | Type `dataset` as a public Events dataset. Explore still falls back to `errors`, and unmapped widget types still render as unsupported | `listOrganizationEvents` (×2) | | `issue view` and other org-scoped issue lookups | Send only the `collapse` values the details endpoint reads (`release`, `stats`, `tags`). It ignored `lifetime`/`filtered`/`unhandled`, and the detail response keeps those fields either way. The short-ID endpoint still gets every value | `getOrganizationIssue` | | `issue view` replay lookup | Send `data_source=errors`. `events` isn't a value the endpoint accepts | `getOrganizationReplayCount` | | `issue explain/plan` | Drop `mode=explorer`, which the autofix endpoint never reads | `startOrganizationIssueAutofix` (×2), `getOrganizationIssueAutofixState` | ### Fixed, but still on the helper - **`issue merge`**: now sends `{merge: true}` with numeric IDs. `updateOrganizationIssues` marks every body field required until getsentry/sentry#130348 lands. - **`trace view`**: no longer sends `project` or `limit`, since the endpoint reads neither. It stays on the helper until getsentry/sentry#130349 documents `timestamp`. An unknown project in `trace view org/project/<id>` still fails as before. - **Dashboard and explore time series**: get the same typed `dataset`, but stay on the helper until #130349 fixes `yAxis`/`interval`. - **AI conversations list**: untouched, because it's waiting on getsentry/sentry#130350 (`sort`). ### Kept on purpose - **`replay list`** keeps requesting `info_ids` and `warning_ids`. The server computes them and `replay list --json` prints them, so dropping them would change the output. `fetchReplayPage` stays on the helper, and a comment says why. ### Behavior notes - On the moved calls, errors use the SDK wording already used by the moved calls in #2073 and by the metric alert path, e.g. `Failed to list issue alert rules: 403 Forbidden`. They no longer start with `API request failed:`, and they no longer have an `Endpoint:` line. Status codes and the 401/403 enrichment are unchanged. - Existing bug, not fixed here: `trace view org/project/<id>` prints "Filtered to project", but the trace endpoint has returned spans from every project since getsentry/sentry#87314. - Docs gap: with `returnIds=true`, the replay-count response maps each issue ID to a list of replay IDs. The documented schema describes counts. The CLI keeps validating that response with its own schema. ### Verification - `pnpm run tsc` and `pnpm run lint` pass. - CLI tests: 12884 pass and 5 fail. All 5 are the sandbox-only permission tests that fail on `main` too (`completions` ×2, `upgrade` acquireLock, `db/resilient` readonly, `dsn/code-scanner`). - Unit tests were updated or added for each changed request shape, including the new `test/lib/api/code-mappings.test.ts`. - API discovery no longer lists the moved call sites. <!-- junior-request-attribution:start --> via @BYK. <!-- junior-request-attribution:end --> <!-- junior-session-footer:start --> <!-- junior-conversation-id:agent%3A80220b9d4c297e2a971f05dcb03af515 --> -- [View Session](https://junior-prod.sentry.dev/conversations/agent%3A80220b9d4c297e2a971f05dcb03af515) [[Sentry]](https://sentry.sentry.io/explore/conversations/agent%3A80220b9d4c297e2a971f05dcb03af515/?project=4510944073809921) <!-- junior-session-footer:end --> Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com> Co-authored-by: BYK <126780+BYK@users.noreply.github.com>
BYK
pushed a commit
that referenced
this pull request
Nov 7, 2026
…2078) Next step after #2073 and #2075, which moved the CLI onto the generated `@sentry/api` operations. `@sentry/api` 1.46.0 includes the API docs fixes from getsentry/sentry#130348, #130349 and #130350, so six more call sites now match their generated operation. This PR bumps the package and moves them. ### Moved onto generated operations | Command(s) | Call | Operation | Unblocked by | | --- | --- | --- | --- | | `issue resolve/unresolve/archive`, `feedback resolve/spam/…` (org-scoped) | `updateIssueStatus` | `updateOrganizationIssue` | sentry#130348 (body fields no longer all required) | | `issue merge` | `mergeIssues` | `updateOrganizationIssues` with numeric `id`s and `{merge: true}` | sentry#130348 | | `dashboard view` chart widgets | `queryWidgetTimeseries` | `listOrganizationEventsTimeseries` | sentry#130349 (`yAxis` array, `interval` int or duration) | | `explore` time series | `queryEventsTimeSeries` | `listOrganizationEventsTimeseries` | sentry#130349 | | `agent-conversation list` | `listConversations` | `listOrganizationAiConversations` with `sort` | sentry#130350 | | `trace view`, `span view`, `log view` | `getDetailedTrace` | `getOrganizationTrace` with `timestamp` | sentry#130349 | Trace meta already used `getOrganizationTraceMeta` and doesn't send `timestamp`, so nothing changes there. ### Behavior notes - Responses are validated exactly as before: `EventsTimeseriesResponseSchema` for widgets and `ConversationListItemSchema` for conversations. The explore time series and trace detail responses were not validated before and still aren't. - `issue merge` still turns a 204 (no matching issues) into the same friendly error, and still clears each affected issue's cross-origin cache. - `agent-conversation list --sort` is now typed with the endpoint's sort enum. The command's sort values are a subset of it. - Errors on the moved calls use the SDK wording, as in #2073 and #2075, e.g. `Failed to update issue: 403 Forbidden`. Status codes and the 401/403 enrichment are unchanged. - The 1.46.0 regen also changes `uniqueValues`/`key`/`name` descriptions in the generated `issue` skill reference, which is committed here. Typecheck is otherwise unaffected. ### Remaining `apiRequest*` call sites and raw fetches Details for each are in getsentry/sentry#130351. **Not in the public schema** (needs a getsentry/sentry API docs decision): - `organizations.ts:66`, `projects.ts:576/591`: region lookups - `users.ts:21`: current user - `trials.ts:30/70`: trials list/start - `org-auth-tokens.ts:77`: delete org auth token - `dashboards.ts:201/235`: dashboard revisions/restore - `issues.ts:329`: unscoped `GET /issues/{id}/` - `issues.ts:632`: legacy unscoped `PUT /issues/{id}/` - `logs.ts:486`: logs query - `traces.ts:225`: trace-items detail (experimental) - `releases.ts:425`: release set-commits - `preprod-artifacts.ts:283/449`: build/snapshot upload - Raw fetches: `getSharedIssue` (`issues.ts`) and `openSnapshotArchive` (`preprod-artifacts.ts`) **Dynamic request identity / transport:** - `auth.ts:17` - `org-auth-tokens.ts:37/59` - `preprod-artifacts.ts:508/526`: snapshot downloads **Kept on purpose:** - `replays.ts:201`: `replay list` keeps requesting `info_ids`/`warning_ids` because `--json` prints them (see #2075). The Oxlint rule that bans the helpers comes last, after these are resolved. ### Verification - `pnpm install --frozen-lockfile` passes with the committed lockfile. - `pnpm run tsc` and `pnpm run lint` pass. - CLI tests: 12919 pass and 5 fail. All 5 are the sandbox-only permission tests that also fail on `main` (`completions` ×2, `upgrade` acquireLock, `db/resilient` readonly, `dsn/code-scanner`). - The dashboard time series tests now mock `listOrganizationEventsTimeseries`. I added an org-scoped `updateIssueStatus` test. The conversation, explore and trace tests run at the fetch layer and pass unchanged. - API discovery no longer lists the moved call sites. <!-- junior-request-attribution:start --> via @BYK. <!-- junior-request-attribution:end --> <!-- junior-session-footer:start --> <!-- junior-conversation-id:agent%3A80220b9d4c297e2a971f05dcb03af515 --> -- [View Session](https://junior-prod.sentry.dev/conversations/agent%3A80220b9d4c297e2a971f05dcb03af515) [[Sentry]](https://sentry.sentry.io/explore/conversations/agent%3A80220b9d4c297e2a971f05dcb03af515/?project=4510944073809921) <!-- junior-session-footer:end --> Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
7 tasks done
This was referenced Nov 7, 2026
BYK
added a commit
to getsentry/sentry
that referenced
this pull request
Nov 7, 2026
Publishes `GET
/api/0/organizations/{organization_id_or_slug}/trace-logs/`
(`OrganizationTraceLogsEndpoint`, owner Data Browsing) in the public API
schema, so it reaches the generated `@sentry/api` SDK.
This comes from the #130351 proposal. The Sentry CLI is moving every
call onto `@sentry/api` operations (getsentry/toolkit#2073), and `log
list` and `trace logs` still call this endpoint by hand because it isn't
in the schema.
Evidence:
- The endpoint has existed since #92501 (2025-05). #126626 documented it
fully with `extend_schema` but left it `PRIVATE`.
- Current callers: the trace view and logs explore pages
(`useTraceOverviewData`, `useLogsApiOptions`) and the CLI's `log list`
and `trace logs` commands.
The response type was `list[dict[str, Any]]`, which the
response-coverage check rejects for public operations. The endpoint
always selects the same eight columns, so each row is now a `TraceLog`
TypedDict, and every field has an `ApiDescription`. I checked the types
against a real response from the endpoint: `project.id` and
`timestamp_precise` are integers, `timestamp` is ISO 8601, and
`confidence` is one empty object per row because logs aren't aggregated.
The example's `timestamp_precise` was a float, so it's now an integer.
`full_scan`, `bytes_scanned` and `routingHint` are optional, because a
mocked or empty RPC meta can leave them out.
The only change to the built schema (`make build-api-docs`, diffed
against master) is the new `listOrganizationTraceLogs` operation and its
`TraceLogsResponse` component. The new apidocs test validates a stored
log against the schema.
`tests/snuba/api/endpoints/test_organization_trace_logs.py::test_simple`
failed once under `-n3` because tests share trace IDs in Snuba. It
passes when the file runs serially.
The "(Optional) Shows the difference between the prod and dev schema"
check is expected to fail, because this PR changes the schema.
<!-- junior-request-attribution:start -->
via @BYK.
<!-- junior-request-attribution:end -->
<!-- junior-session-footer:start -->
<!-- junior-conversation-id:agent%3A22c5e57fa755cece5122380dcb72ec8e -->
--
[View
Session](https://junior-prod.sentry.dev/conversations/agent%3A22c5e57fa755cece5122380dcb72ec8e)
[[Sentry]](https://sentry.sentry.io/explore/conversations/agent%3A22c5e57fa755cece5122380dcb72ec8e/?project=4510944073809921)
<!-- junior-session-footer:end -->
---------
Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
Co-authored-by: BYK <126780+BYK@users.noreply.github.com>
BYK
added a commit
that referenced
this pull request
Nov 7, 2026
…cated endpoints (#2090) Fixes #2089. The CLI still called two Sentry routes that were deprecated on 2026-05-15 for cell routing (`CELL_API_DEPRECATION_DATE`). On SaaS, both can return 410 during brownouts: - unscoped `GET`/`PUT /issues/{id}/`, for numeric issue lookups and status updates without an org - `GET /projects/?query=dsn:<key>`, for DSNs with no `o<id>` in the host ### Issues - `getIssue` (unscoped) is removed. A numeric ID with no org now goes through `findIssueInOrgs`, which asks the user's orgs concurrently (`ORG_FANOUT_CONCURRENCY`) through `getOrganizationIssue`. No new request starts once one org returns the issue. 404/403 count as "not here". Any other error is thrown only if no org has the issue. - `resolveOrgAndIssueId` caches the owning org as before. A stale cache entry still triggers a fresh search. - `updateIssueStatus` now requires `orgSlug` and always uses `updateOrganizationIssue`. Every caller already had the org, so the dead `!org` guards in `issue events/resolve/tags/merge` are gone. - The unscoped completion sources and the legacy `/issues/{id}/` cache invalidation in `mergeIssues` and `issue-links` are removed. Nothing reads that cache anymore. - There's no fallback to the unscoped route. Org-scoped issue routes exist on every Sentry since 24.1. ### DSN lookup - `findProjectByDsnKey` is replaced by `findProjectByDsn(dsn, publicKey)`. It asks each of the user's orgs with `GET /organizations/{org}/dsn-lookup/?dsn=`, routed to the org's region. The endpoint is still private (getsentry/sentry#130351), so this stays on `apiRequestToRegion` with a valibot schema until it's published. - A 404 with `DSN not found` / `Invalid DSN` means "not in this org". Any other 404 means the server has no dsn-lookup, which happens on self-hosted from before 2026-02, or before the flag removal on 2026-04. Then, and only on non-SaaS hosts, the CLI falls back to `/projects/?query=dsn:`. Sentry doesn't brown out deprecated routes on self-hosted. On SaaS the deprecated route is never called. - It no longer needs `/users/me/regions/`. ### Cost Both lookups now fan out per org instead of making one request (issues) or one per region (DSN). They run only when there's no org context and no cache hit, they reuse the cached org list, and they stop starting requests at the first hit. ### Tests - New `findProjectByDsn` suite in `api-client.multiregion.test.ts`: found, miss, a per-org failure, the self-hosted fallback, and no fallback on SaaS. - `findIssueInOrgs` coverage tests. - `issue/utils` tests for the org search, a stale cache, the cache write, and a 5xx. - Updated the resolver, resolve-target, completion-cache and issue-links tests. ### Gate `pnpm run tsc && pnpm run lint` pass. In `pnpm run test`, the CLI has 5 failures, and they're the known sandbox file-permission tests (completions ×2, upgrade, db/resilient, dsn/code-scanner). Every other package passes. `@sentry/cli3to4` can't run here because the codemod binary needs GLIBC_2.35. Related: #2073 (the CLI's move onto `@sentry/api` operations), getsentry/sentry#130351 (the private endpoints the CLI uses, dsn-lookup among them). <!-- junior-request-attribution:start --> via @BYK. <!-- junior-request-attribution:end --> <!-- junior-session-footer:start --> <!-- junior-conversation-id:agent%3A80220b9d4c297e2a971f05dcb03af515 --> -- [View Session](https://junior-prod.sentry.dev/conversations/agent%3A80220b9d4c297e2a971f05dcb03af515) [[Sentry]](https://sentry.sentry.io/explore/conversations/agent%3A80220b9d4c297e2a971f05dcb03af515/?project=4510944073809921) <!-- junior-session-footer:end --> --------- Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com> Co-authored-by: BYK <126780+BYK@users.noreply.github.com>
BYK
added a commit
that referenced
this pull request
Nov 7, 2026
… revision operations (#2093) Next batch of moving the CLI onto `@sentry/api` generated operations (follows #2073, #2075, #2078, #2090). `@sentry/api` 1.49.0 publishes three endpoints the CLI already calls: | CLI function | Endpoint | Operation | Published by | | --- | --- | --- | --- | | `listTraceLogs` (`log list --trace`, `trace logs`) | `GET /organizations/{org}/trace-logs/` | `listOrganizationTraceLogs` | getsentry/sentry#130357 | | `listDashboardRevisionsPaginated` (`dashboard revisions`) | `GET /organizations/{org}/dashboards/{id}/revisions/` | `listOrganizationDashboardRevisions` | getsentry/sentry#130358 | | `restoreDashboardRevision` (`dashboard restore`) | `POST /organizations/{org}/dashboards/{id}/revisions/{rev}/restore/` | `restoreOrganizationDashboardRevision` | getsentry/sentry#130358 | These calls stop using `apiRequestToRegion` and behave the same as before: - The CLI's valibot schemas still validate each response, so schema mismatches still fail as "Unexpected response format". - Region routing goes through `getOrgSdkConfig`. - Pagination still uses the Link-header cursors, including the previous cursor for revisions. - 401/403 errors are still enriched by `unwrapResult`. - On the wire, `traceId` and `sort` are sent as single repeated params, the same as before. - The dashboard and revision ids are passed as strings with the same cast `getDashboard` uses. The SDK URL-encodes them the way the old code did. All three operations have `experimental: false`. Bumping to 1.49.0 also pulls in the 1.47.0 regen and 1.48.0's `experimental` flag. Typecheck and generated docs don't change. ### Still on the helpers | Call site | Endpoint | Waiting on | | --- | --- | --- | | `issues.ts` `getSharedIssue` (raw fetch) | `GET /shared/issues/{share_id}/` | getsentry/sentry#130359 merged after the 1.49.0 regen, so it needs the next release | | `releases.ts` set-commits | `GET /organizations/{org}/releases/{version}/previous-with-commits/` | same as above (#130359) | | `org-auth-tokens.ts` (3 sites) | list/create/delete `/organizations/{org}/org-auth-tokens/` | getsentry/sentry#130360 (auto-merging) | | `projects.ts` dsn-lookup | `GET /organizations/{org}/dsn-lookup/` | getsentry/sentry#130367 | | `auth.ts` | `GET /api/0/` (control silo) | getsentry/sentry#130369 | | `users.ts` | `GET /auth/` → `GET /users/me/` | getsentry/sentry#130368 | | `organizations.ts` | `GET /users/me/regions/` | #2091 replaces it with `listOrganizations` | | `traces.ts` / `logs.ts` | `GET /projects/{org}/{project}/trace-items/{id}/` | sentry publish PR still to come | | `preprod-artifacts.ts` | build assemble, snapshot archive status and trigger, snapshot create (zstd body) | sentry publish PRs still to come | | `projects.ts` | `GET /projects/?query=dsn:` fallback for old self-hosted servers | not public; needs a decision (see below) | These are the agreed exceptions: `trials.ts` (`/customers/*` and the product-trial PUT), snapshot `upload-options` and archive `?download`, `downloadBuildArtifact`'s install URL, chunk-upload server URLs, and `rawApiRequest` for `sentry api`. **Needs a decision:** the self-hosted DSN fallback from #2090 calls `GET /projects/?query=dsn:`, which isn't in the public schema. It needs to be added to the exception list for the lint rule, or dropped once old self-hosted versions age out. ### Testing - `pnpm run tsc` and `pnpm run lint` pass. - `pnpm run test` fails only on the 5 file-permission tests that also fail on `main` in the sandbox (`completions` ×2, `upgrade`, `db/resilient`, `dsn/code-scanner`), plus `@sentry/cli3to4`, whose codemod binary needs GLIBC 2.35. - Added unit tests for the revision list (cursors, schema rejection) and for restore (operation args, error naming). The trace-logs test now checks `traceId` and `sort` on the wire. <!-- junior-request-attribution:start --> via @BYK. <!-- junior-request-attribution:end --> <!-- junior-session-footer:start --> <!-- junior-conversation-id:agent%3A80220b9d4c297e2a971f05dcb03af515 --> -- [View Session](https://junior-prod.sentry.dev/conversations/agent%3A80220b9d4c297e2a971f05dcb03af515) [[Sentry]](https://sentry.sentry.io/explore/conversations/agent%3A80220b9d4c297e2a971f05dcb03af515/?project=4510944073809921) <!-- junior-session-footer:end --> Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com> Co-authored-by: BYK <126780+BYK@users.noreply.github.com>
BYK
added a commit
that referenced
this pull request
Nov 9, 2026
…eveApiIndex (#2118) Bumps `@sentry/api` from 1.53.0 to 1.55.0 and moves the CLI's `GET /api/0/` call onto the generated `retrieveApiIndex` operation. getsentry/sentry#130369 published that endpoint, and 1.55.0 ships it. ## Change `getCurrentAuthScopes` (`packages/cli/src/lib/api/auth.ts`) feeds scope recovery. It used to call the raw `apiRequestToRegion(getControlSiloUrl(), "")` helper. It now calls `retrieveApiIndex` with `getSdkClientConfig(getControlSiloUrl())`, then `unwrapValidatedResult` with the same valibot schema. This is the same pattern as `org-auth-tokens.ts`. Behavior is unchanged: - It still goes to the control silo URL. That's the configured server URL on self-hosted, so self-hosted works as before. - `auth: null` still returns `null`. Sentry sends that for anonymous requests, session requests and requests with no token, and scope recovery treats it as `invalid`. - A 401 still comes back as an `ApiError` with `status: 401`. That's the case `scope-recovery.ts` checks. CLI errors thrown by the fetch layer, such as `AuthError`, still pass through `unwrapResult` unchanged. With this change, the API discovery step in `typecheck` no longer reports `auth.ts` as "not in the public catalog". ## Bump - `pnpm-workspace.yaml`: the catalog and `minimumReleaseAgeExclude` both move to `@sentry/api@1.55.0`. - `pnpm-lock.yaml`: the `@sentry/api` entries move to 1.55.0 and its integrity. 1.55.0 has the same dependencies and peer dependencies as 1.53.0. - `pnpm install --no-frozen-lockfile` wouldn't rewrite these entries. pnpm's lockfile age check rejected the old 1.53.0 entry before it resolved anything, even with 1.53.0 temporarily excluded, so I edited the entries by hand. - `pnpm install --frozen-lockfile` passes on the result, age policy check included. - 1.54.0 and 1.55.0 cause no other type errors. Neither the CLI docs nor the skill references changed when regenerated. ## Still waiting on sentry - dsn-lookup: getsentry/sentry#130367 - `/auth/` → `GET /users/me/`, falling back to `/auth/` on a 403 from older self-hosted servers: getsentry/sentry#130368 - trace items (`traces.ts`, logs): getsentry/sentry#130373 - After those, the no-allowlist Oxlint rule. ## Gate (local sandbox) - `pnpm run tsc`: passes. - `pnpm run lint`: passes. - Tests: - These all pass: mcp-core, mcp-cloudflare, mcp-test-client, toolkit-core, logger, apps/local, apps/docs-mcp, apps/games-api and apps/cli-docs. - CLI: 12952 pass and 5 fail. All 5 are the known sandbox-only permission cases: completions ×2, upgrade lock, resilient DB and the code-scanner unreadable-file test. - `@sentry/cli3to4` can't run here, because its `codemod` binary needs GLIBC 2.35. - `test/lib/api/auth.test.ts` now mocks `retrieveApiIndex` and covers scopes, `auth: null`, and the 401. No UI change, so no screenshots. Part of the `@sentry/api` migration that started in #2073 (tracking issue: getsentry/sentry#130351). <!-- junior-request-attribution:start --> via @BYK. <!-- junior-request-attribution:end --> <!-- junior-session-footer:start --> <!-- junior-conversation-id:agent%3A80220b9d4c297e2a971f05dcb03af515 --> -- [View Session](https://junior-prod.sentry.dev/conversations/agent%3A80220b9d4c297e2a971f05dcb03af515) [[Sentry]](https://sentry.sentry.io/explore/conversations/agent%3A80220b9d4c297e2a971f05dcb03af515/?project=4510944073809921) <!-- junior-session-footer:end --> Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com> Co-authored-by: Burak Yigit Kaya <126780+BYK@users.noreply.github.com>
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is step 1 of moving the CLI onto
@sentry/apigenerated operations. The goal is an Oxlint rule that bans theapiRequest*helpers with no allowlist. @BYK chose that scope ("Also ban apiRequest* helpers") when the lint follow-up to #2062 was scoped. Since the rule can't land until every call site has moved, it isn't in this PR.#2062 bumps
@sentry/apito 1.44.0 too and moveslib/objectstore.ts. This PR leavesobjectstore.tsalone, so whichever PR merges second only needs a lockfile rebase.What changed
@sentry/api1.26.0 → 1.44.0 in the catalog and inminimumReleaseAgeExclude. The regeneratedalert.mdandevent.mdskill references are included.apiRequest*call sites now use generated operations:deleteIssueAlertRule→deleteOrganizationWorkflowgetChunkUploadOptions→getOrganizationChunkUploadOptions.ChunkServerOptionsSchemastill validates the response because the SDK type doesn't includemaxWait.assembleDebugFiles→assembleProjectDebugFilesassembleArtifactBundle→assembleOrganizationArtifactBundlepollAssembly/pollDifAssemblytake anassemblecallback.getConversationSpans→retrieveOrganizationAiConversationgetIssueByShortId→resolveOrganizationShortIdgetBuildInstallDetails→getOrganizationPreprodArtifactInstallDetailsgetOrganizationPreprodArtifactSnapshotLatestBase(a 404 still returnsnull)setCommitsWithRefs→updateOrganizationRelease. The./..path-segment checks stay because the SDK's path serializer lets them through.getReplay→getOrganizationReplaygetTraceMeta→getOrganizationTraceMetafetchTransactionsPage/fetchSpansPage→listOrganizationEventsinfrastructure.tsgetsvalidateResponseandunwrapValidatedResult, so call sites that already validated responses with Zod still do that on SDK results. No newascasts on query or body types.Behavior notes
<context>: <status>(fromunwrapResult/throwApiError) instead ofAPI request failed: …. The 401/403 enrichment is unchanged.throwApiErrordoesn't attach theapi_response_headersSentry context that the helper path set.getOrgSdkConfig), caching and idempotency are unchanged.Tests
chunk-upload.test.tsandproguard.test.tsnow test at the fetch level (mockFetch+setOrgRegion). New cases covermaxWait, schema mismatch, 404, and both assemble endpoints.debug-files.test.tsmocks the newassembleDebugFiles.preprod-artifacts.test.tsmocksgetOrgSdkConfig, with new cases for a null body, a 500, and a schema mismatch.Gate
pnpm run tscandpnpm run lint: pass.pnpm run test: fails only on sandbox environment problems that also fail onmain. CI is the real check.codemod-cli3to4because the sandbox lacksGLIBC_2.35.pnpm -r --no-bail run test: every package passes except the CLI, which has 5 failures (12881 passed). All 5 are file-permission tests that fail onmainin the same sandbox:completions(2),upgradeacquireLock,db/resilientreadonly, anddsn/code-scannerunreadable files.Remaining call sites (39 + 2 raw fetches)
(a) Missing from the public schema: needs getsentry/sentry API docs
auth.tsGET/api/0/(root). Used for the token check; dynamic.dashboards.tsGET/organizations/{org}/dashboards/{id}/revisions/dashboards.tsPOST/organizations/{org}/dashboards/{id}/revisions/{rev}/restore/issues.tsGET/issues/{id}/(unscoped issue lookup)issues.tsPUT/issues/{id}/(unscoped update fallback)issues.tsrawcustomFetchGET/shared/issues/{shareId}/(getSharedIssue)logs.tsGET/organizations/{org}/trace-logs/org-auth-tokens.tsGET, POST/organizations/{org}/org-auth-tokens/, DELETE…/{tokenId}/organizations.tsGET/users/me/regions/preprod-artifacts.ts:/projects/{org}/{project}/files/preprodartifacts/assemble/(build assemble)…/preprodartifacts/snapshots/upload-options/…/snapshots/{id}/archive/customFetchopenSnapshotArchiveprojects.tsGET/organizations/{org}/projects/?query=dsn:{key}(×2). The list op has noqueryparam.releases.tsGET/organizations/{org}/releases/{version}/previous-with-commits/traces.tsGET/projects/{org}/{project}/trace-items/{itemId}/trials.tsGET/customers/{org}/and PUT/customers/{org}/product-trial/users.tsGET/auth/These look intentionally private, so publishing them needs a call from the API owners:
/customers/*(billing, getsentry),/users/me/regions/, the/api/0/root,/auth/,previous-with-commits,trace-logs,trace-items, and the preprod/snapshot internals.(b) In the schema, but the generated types don't match what the CLI sends or reads
alerts.ts×2, GET/organizations/{org}/workflows/: noprojectSlugfilter, and the CLI sends string ids.code-mappings.tsPOST bulk code mappings: the CLI sends a camelCase body; the schema is snake_case.conversations.tslist: nosortquery param.dashboards.tsevents-timeseries:yAxisis an array anddatasetis optional in the CLI.dashboards.tsevents:datasetcan be null or a value outside the enum.explore.tsevents-timeseries: arrayyAxis, stringinterval.explore.tsevents: free-form dataset.issues.tsGET org issue: thecollapseenum is onlyrelease|stats|tags.issues.tsPUT org issue: every update body field is required.issues.tsPUT/organizations/{org}/issues/(merge):updateOrganizationIssuesalso requires every body field.replays.tslist: thefieldenum lacksinfo_ids/warning_ids.replays.tsreplay-count: nodata_source=events.seer.ts×3,/organizations/{org}/issues/{id}/autofix/: nomode=explorer.traces.tsGET/organizations/{org}/trace/{id}/: notimestamp/limit/projectparams.preprod-artifacts.tsPOST…/preprodartifacts/snapshots/: the body type isnever, and the CLI sends a zstd body.(c) Dynamic or upload transport, not Sentry API operations
installUrl.rawApiRequest/prepareRawApiRequestback thesentry apipassthrough command.via @BYK.
--
View Session [Sentry]