Add issue update --unassign to clear an issue's assignee#249
Merged
Conversation
There was no way to unassign an issue. The mutation input was built as a `Record<string, string | number | string[] | undefined>`, a type that structurally cannot hold null, so `IssueUpdateInput.assigneeId` could never be set to null no matter what flags were added. Swap that hand-rolled Record for the codegen'd `IssueUpdateInput` — matching what `project update` already does — and add an explicit `--unassign` flag. Passing both --assignee and --unassign is a ValidationError rather than one silently winning. No short alias: `-U, --unassigned` is already bound in three sibling commands as a read-side filter, and putting a data-clearing mutation one shift-key away from a harmless filter invites accidents. Verified against the real API that Linear honors `assigneeId: null` — worth checking explicitly, since it silently ignores `projectId: null` elsewhere.
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.
There was currently no way to unassign an issue.
Root cause
The mutation input was built as
Record<string, string | number | string[] | undefined>— a type that structurally cannot holdnull. SoIssueUpdateInput.assigneeIdcould never be set tonull, no matter what flag was added on top. Adding a flag alone would not have compiled.Change
Recordfor the codegen'dIssueUpdateInput.project updatealready does this (project-update.ts:152), so this restores consistency rather than introducing a pattern. Type check confirmed zero fallout across every existing field assignment.--unassign, which sendsassigneeId: null.--assigneeand--unassignraises aValidationErrorwith a suggestion, rather than one silently winning. The guard runs before any network or VCS call.No short alias
-U, --unassignedis already bound in three sibling commands (issue-query.ts:73,issue-mine.ts:118,issue-start.ts:25) as a read-side filter. Binding-u, --unassignwould put a data-clearing mutation one shift-key from a harmless filter. Long-form only; an alias can be added later but never removed.Verification
Linear silently ignores
projectId: nullelsewhere in this codebase (document-update.ts:214), so mocked tests alone could not prove this works. Verified against the real API on a throwaway issue: assignee cleared, issue then deleted.Tests assert the wire payload by pinning the mock's
inputto an exact shape, which is load-bearing — the mock matcher compares nested objects by exact key count, so a regression toundefineddrops the key and fails to match. Confirmed by deliberately reverting the implementation and watching the tests fail.Follow-ups (not in this PR)
--project,--cycle,--parent, and--milestone. The type migration here unblocks each as roughly a one-liner.issue createstill builds its input as a loose object rather thanIssueCreateInput.Deno.consoleSize(), so regenerating on a different terminal reflows unrelated files. Only the real--unassignline is included here to avoid that churn.