feat: fully migrate to @sentry/api SDK types (remove all as-unknown-as casts)
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 35/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Quiet
- Tech stack
- typescript
- Domain
- api, backend-api-design, cli
Research direction
Read src/lib/api/infrastructure.ts and the callers under src/lib/api/ to understand the generic unwrapResult work and remaining casts. Check the backend schema changes needed in getsentry/sentry and sentry#116836 before removing dependent casts; done means grep -c "as unknown as" src/lib/api/*.ts reports 0.
Written by the indexing model from the issue text.
Description
Background
The CLI already uses @sentry/api for all API calls (~60+ SDK functions in production). However, 30 as unknown as casts remain in src/lib/api/ — TypeScript bridges between SDK-generated response types and the CLI's internal SentryXxx wrapper types. These casts don't hide real bugs (the runtime shapes match), but they prevent TypeScript from catching future regressions and make the codebase harder to maintain.
This issue tracks the work to get to zero casts and fully adopt the SDK-generated types.
Three categories of work
Category 1 — Response type casts (~20 casts, CLI-only, ~2 days)
Pattern: return data as unknown as SentryTeam[]
The CLI defines SentryTeam = Partial<SdkTeam> & { id, slug, name }. TypeScript can't automatically narrow from the SDK's strict union type to this intersection. At runtime the shapes are identical.
Fix: Make unwrapResult<T> generic so the single cast lives in infrastructure, and all callers are clean:
// infrastructure.ts
export function unwrapResult<T>(result: SdkResult<unknown>, context: string): T {
if (result.error !== undefined) { throwApiError(...) }
return result.data as T; // one cast, all callers clean
}
// teams.ts — before
return data as unknown as SentryTeam[];
// after
return unwrapResult<SentryTeam[]>(result, "Failed to list teams");
Also simplify wrapper types that are already 100% compatible with SDK types:
SentryTeam→ aliasSdkTeamdirectlySentryRelease→ aliasPartial<SdkReleaseResponse>SentryDeploy→ alias SDK type directly
Category 2 — Request body casts (~7 casts, needs backend spec fix)
Pattern: body as unknown as Parameters<typeof sdkFn>[0]["body"]
The SDK marks certain request body fields as required (per the spec), but the CLI passes them as optional and the API silently accepts it. Fixing the spec makes the cast unnecessary.
Backend spec changes needed (getsentry/sentry PRs):
| Endpoint | Field(s) to mark optional |
|---|---|
createANewDashboardForAnOrganization |
widgets |
editAnOrganization_sCustomDashboard |
various fields |
createANewReleaseForAnOrganization |
projects |
updateAnOrganization_sRelease |
various fields |
After each backend fix ships in a new @sentry/api release, the corresponding CLI cast can be removed.
Category 3 — Path parameter casts (3 casts, CLI-only, trivial)
Pattern: dashboard_id: dashboardId as unknown as number
Already blocked on sentry#116836 (dashboard_id type fix). Once that ships:
// Before
dashboard_id: dashboardId as unknown as number,
// After
dashboard_id: dashboardId, // string, as the spec now correctly declares
Wrapper types that need to stay (for now)
Three types keep fields beyond the SDK spec that have never been formally documented:
| Type | Extra fields | Fix |
|---|---|---|
SentryOrganization |
allowMemberProjectCreation, orgRole |
Contribute to Sentry backend spec |
SentryProject |
status (undocumented API field) |
Contribute to Sentry backend spec |
SentryEvent |
dateCreated, fingerprints, sdkUpdates, typed contexts |
Some may be intentionally undocumented; contribute where possible |
Work order
- Phase 1 (CLI-only, ~2 days): Make
unwrapResult<T>generic; drop response-type casts; simplify compatible wrapper types; replacedashboard_idcast withparseInt - Phase 2 (Backend spec, ~3 days + release): Fix dashboard and release request body schemas in getsentry/sentry; bump SDK; remove 7 body casts
- Phase 3 (Ongoing): Contribute undocumented fields to spec; narrow/remove remaining wrapper types as each field lands
Success metric
grep -c "as unknown as" src/lib/api/*.ts # 0
- Dominant language
- TypeScript
- Stars
- 121
- Forks
- 14
- Avg merge
- 22h 3m
- Merged PRs (30d)
- 94
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from getsentry/cli
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
Difficulty 3/5 1-2 days Newbie friendliness 68/100
-
Difficulty 3/5 1-2 days Newbie friendliness 65/100
-
bug jared
-
jared
Difficulty 4/5 3-5 days Newbie friendliness 52/100
Similar issues
-
Browser Waiting for: Product Owner
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
getsentry/sentry-javascript#24577 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
agilepathway/label-checker#640 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
copse-dev/agent-pane#2953 ·
-
agentic-workflows
Difficulty 1/5 Under an hour Newbie friendliness 85/100
githubnext/rig#534 ·
-
automation missing-model model-sync provider:pioneer
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
anomalyco/models.dev#7701 ·