Repository navigation
docs(issues): Mark issue update body fields as optional - #130348
Merged
Merged
Conversation
The single and bulk issue update endpoints always run GroupValidator with partial=True, so a request only has to send the fields it changes. The validators still declared every field as required, so the OpenAPI schema listed all of them, and every statusDetails field, as required in the request body. Generated clients such as @sentry/api then type every field as required, so a body that only sets status or assignedTo fails to typecheck. Mark the fields required=False so the docs match what the endpoints accept. Validation is unchanged because partial=True already skipped the required check. Refs getsentry/toolkit#2073 Co-Authored-By: BYK <[email protected]>
BYK
approved these changes
Nov 7, 2026
BYK
added a commit
to getsentry/toolkit
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 <[email protected]>
BYK
pushed a commit
to getsentry/toolkit
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>
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.
The OpenAPI schema for
PUT /organizations/{org}/issues/{issue_id}/(updateOrganizationIssue) andPUT /organizations/{org}/issues/(updateOrganizationIssues) listed everyGroupValidatorfield, and everystatusDetailsfield, as required. The endpoints always validate withpartial=True(validate_requestinapi/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, becausepartial=Truealready skipped the required check. Only the two operations above change in the generated schema. Their request body schemas lose therequiredlists, and the body itself is no longer marked required.The Sentry CLI needs this to move its issue update calls onto the generated
@sentry/apioperations (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,GroupUpdateTestintest_organization_group_index.py,tests/sentry/api/helpers/test_group_index.py, prek and mypy. Under xdist, three snuba-backedGroupUpdateTestcases failed:test_resolve_with_integration,test_snooze_user_countandtest_bulk_resolve. Run serially, they pass on this branch and on master.via @BYK.
--
View Session [Sentry]