-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Description
Summary
The ownership rules widget breaks when an actor's name field receives a numeric value (team internal ID) instead of a string. This happens because the API response schema uses identifier (e.g. a team slug or user email) renamed to name, but the id field in the schema holds the raw integer DB id — and when avatar/display code receives that integer as name, getInitials() calls name.trim() which fails at runtime since integers don't have .trim().
Root Cause
The GET /api/0/{org}/{project}/ownership/ endpoint calls rename_schema_identifier_for_parsing() which renames identifier → name in each owner entry. The schema also includes a numeric id field (set by add_owner_ids_to_schema) — so each owner in the API response looks like:
{ "type": "team", "name": "#my-team", "id": 2251960 }The frontend types this as Actor ({ id: string, name: string, type }), but the id coming from the backend is a number, not a string. In ownershipRulesTable.tsx, the code does:
const team = TeamStore.getById(owners[0].id);When TeamStore.getById returns null (e.g. team not in store), the fallback path reaches getInitials(owners[0].name) in useAvatar.ts. At this point, if name somehow resolves to the numeric id value (e.g. due to a type confusion or a missing name field in a specific data path), name.trim() throws because integers have no .trim() method.
Observed in the debugger: name = 2251960 (a number), sanitizedName unavailable, confirming the value passed as name is a team's integer ID.
Additionally, the Actor type on the frontend declares id: string, but the API returns id as a number — this type mismatch may contribute to the bug in downstream identity comparisons.
Reproduction
- Set up ownership rules that reference a team.
- Open the ownership rules widget for a project in the demo org.
- If the team is not loaded in
TeamStore(e.g. demo org, stale store), the widget errors rendering the avatar.
Expected Behavior
getInitials()should guard against non-stringnameinputs (e.g.String(name)coercion or early return).- The API should ensure
idis serialized as a string to match the frontendActortype, or the frontend should coerce it. TeamStore.getByIdlookup should handle string/number id mismatch gracefully.
Files
src/sentry/issues/endpoints/project_ownership.py—rename_schema_identifier_for_parsing+add_owner_ids_to_schemastatic/app/components/core/avatar/useAvatar.ts—getInitials()(no type guard)static/app/views/settings/project/projectOwnership/ownershipRulesTable.tsx— owner avatar rendering
Action taken on behalf of Max Kosty.