Skip to content

fix(unassign): base the unassign label set on live GitHub labels instead of the cached row #1366

Closed

Description

@itsmiso-ai

Base the label set that POST /api/issues/unassign writes on the live GitHub labels instead of the cached Prisma row, so an unassign can no longer silently strip a label that was added on GitHub since the last sync.

Expected files: src/app/api/issues/unassign/route.ts and its test file (src/app/api/issues/unassign/route.test.ts).

Context:

  • updateIssueLabels is a FULL-label-set PUT — it replaces all labels. The unassign route computes that set from issue.labels (the Prisma cache) minus the labels of the requested type.
  • The codebase already states the rule this breaks, in src/lib/issue-claim.ts: "Only targeted label writes reach GitHub here … Never replace the whole label set — the cached row be behind GitHub, and a full-set write would silently revert every label change made on GitHub since the last sync."
  • The sibling assign route (src/app/api/issues/actions/route.ts) already complies: it reads the live label set through getLiveIssueLabels and fails closed with a 503 when GitHub is unreachable.
  • The unassign route cannot succeed without GitHub anyway (it PUTs the label set), so a live read costs no availability: a GitHub outage already fails the write.
  • The per-issue mutation anchor that fix(ownership): guard the remote agent/* label write in POST /api/issues/unassign #1361 added to this route is the right place to take the live read — the label-set decision must happen while the anchor is held, so the snapshot the PUT applies is the one the anchor saw.

Acceptance:

  • The label set the unassign writes is derived from the live GitHub labels (minus the agent/owner labels of the requested type), not from the cached row.
  • GitHub unreachable → fail closed: no remote write, no cache write, a failure audit row, and a 503 — the same shape the assign route uses.
  • The live read happens inside the per-issue mutation anchor, and the remote write stays inside the fenced write.

Follow-up to #1361 (the anchor/fence for this route), found while reviewing that change.

Activity

  1. added and removed
    status/in-reviewPull request or human review is in progress.
    on Oct 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions