Fix document list --issue, which never worked - #257
Merged
Conversation
The filter was built as issue: { identifier: { eq: ... } }, but IssueFilter
has no identifier field — the comparator for the human identifier is spelled
id. Linear rejected the variable during coercion, so every invocation of the
flag failed before reaching the resolver, regardless of whether the issue
existed. The flag has been broken since the command was introduced.
Type the filter local as DocumentFilter instead of any, which turns this class
of mistake into a compile error rather than a runtime API rejection; deno check
flags the bad field directly. Building the filter as a single annotated
expression also drops the deno-lint-ignore and keeps it undefined when neither
--project nor --issue is passed, so an unfiltered list still sends no filter.
The previous tests here were removed for rendering relative timestamps, which
are non-deterministic. The regression test instead goes through --json, which
prints raw timestamps, and declares the exact request variables so the mock
only matches the correct filter shape — verified by restoring the pre-fix code
and watching it fail.
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 bug
document list --issue <ID>has never worked. The filter was built as:but
IssueFilterhas noidentifierfield — the comparator for the humanidentifier is spelled
id. Linear rejects the variable during coercion, so everyinvocation failed before reaching the resolver:
It fails regardless of whether the issue exists or has documents attached. Broken
since the command was introduced, so this is not a regression.
--projecton thesame command is unaffected.
The fix
issue: { id: { eq: ... } }.IDComparatortakes the human identifier directly,so no identifier parsing is needed.
The filter local was
let filter: any = undefinedwithno-explicit-anysuppressed, which is why the wrong field name compiled. It is now built as a
single annotated
DocumentFilter | undefinedexpression, and the lint suppressionis gone. With the annotation in place
deno checkflags the original bug directly:The filter still stays
undefinedwhen neither flag is passed, so an unfilteredlist sends no filter at all.
Test
The earlier filter tests here were removed for rendering relative timestamps
(non-deterministic, and
fakeTimehangs against the mock server). The new testgoes through
--jsoninstead, which prints raw timestamps, and declares the exactexpected request variables so
MockLinearServeronly matches the correct filtershape.
It is verified to actually guard the bug, not just to pass:
No mock response configured for this query, while the other three tests pass.-- --update, so a careless snapshot regenerationcannot silently re-record a broken filter as expected output. (The mock miss
exits non-zero, and cliffy fails on that regardless of update mode.)
Verification
Every
--project/--issuecombination was exercised against a local captureserver to confirm what actually goes over the wire:
filtersent--issue TC-123{"issue":{"id":{"eq":"TC-123"}}}--issue tc-123{"issue":{"id":{"eq":"TC-123"}}}--project p{"project":{"slugId":{"eq":"p"}}}The
project/issuekeys are set toundefinedwhen their flag is absent and aredropped during serialization, so no phantom key reaches the API.
deno task check,deno lint,deno fmt --checkand the full suite (509 tests) pass.Known limitation, unchanged by this PR
.toUpperCase()is applied to the identifier, which also uppercases a UUID if oneis passed.
IDComparatoraccepts UUIDs as well as human identifiers, anduppercased UUIDs were reported to still match, but that was not independently
verified here. The uppercasing predates this change and is kept so
--issue tc-123works; making it conditional would mean adding identifier-vs-UUID parsing, which
felt out of scope for a bug fix.
Follow-ups (not in this PR)
any-typed-filter pattern insrc/commands/label/label-list.ts:61andsrc/commands/initiative/initiative-list.ts:123.MockLinearServerdoes not validate variables against the schema, sowrong-but-parseable filters can only be caught by pinning variables per test.
document list --jsonprints the whole connection ({nodes, pageInfo}), not abare array — worth a line in the
--jsonhelp text.