You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
CompleteIssueFields carries four unbounded nested connections. Linear's complexity estimator charges an unbounded connection at its default page size (50) per parent row, so issues list and issues search — both defaulting to -l 50 — are priced the same way projects list was in #276, which #284 has just fixed for the projects domain only.
This is the same defect class as #276/#283, in a different (and more frequently used) domain.
Evidence
The unbounded connections in CompleteIssueFields (graphql/queries/issues.graphql):
labels (~line 29)
children (~line 50)
relations (~line 57)
inverseRelations
Consumers that spread it at the root with a user-controlled first:
#284 measured, against the live API, that each issue selected through CompleteIssueFields prices at ~260 (consistent with 4 connections × 50 rows × 1.3). That measurement is what justified lowering projects read --issues-first from 50 to 25 there — empirically it passes at 35 and fails at 40, i.e. a ceiling around 10000/263 ≈ 38 issues.
Applying the same model to issues list at its default limit of 50 gives ~13,000 against the 10,000 budget.
What needs checking first
The ~260 figure was measured for issues nested under a project, not for issues at the query root. Before any code change, someone with a real workspace should run:
linearis issues list
linearis issues search "<term>"
If they fail — this is a live P0-class bug on the most-used command in the tool, and the fix mirrors fix(projects): bound project query connections to avoid complexity limit #284: bound the four connections inside CompleteIssueFields. Note that fragment is shared far more widely than the project fragments were, so this is a cross-domain behaviour change (silent truncation of labels/children/relations per issue) and wants its own measurement pass rather than a copy of the 25s.
If they succeed — the estimator prices root connections differently from nested ones, and the cost model documented in graphql/queries/projects.graphql and src/services/project-service.ts should get a footnote saying so, since it currently reads as universal.
Either outcome is worth having written down.
Related, same shape
src/commands/issues.ts:1471 reads CompleteIssueFields.labels (unbounded, so an implicit 50) and writes the result back as a full-replacement labelIds. An issue with more than 50 labels would therefore lose labels 51+ on issues update --label-mode add. Unreachable in practice, but it is exactly the read-modify-write hazard #284 moved the projects domain off of (its lean pre-read now fetches 250), so the two domains are now inconsistent. Worth fixing in the same pass.
Context
Split out of the review of #284, which deliberately scoped itself to the projects domain. Nothing here regresses because of that PR — this defect predates it.
Summary
CompleteIssueFieldscarries four unbounded nested connections. Linear's complexity estimator charges an unbounded connection at its default page size (50) per parent row, soissues listandissues search— both defaulting to-l 50— are priced the same wayprojects listwas in #276, which #284 has just fixed for theprojectsdomain only.This is the same defect class as #276/#283, in a different (and more frequently used) domain.
Evidence
The unbounded connections in
CompleteIssueFields(graphql/queries/issues.graphql):labels(~line 29)children(~line 50)relations(~line 57)inverseRelationsConsumers that spread it at the root with a user-controlled
first:GetIssues(graphql/queries/issues.graphql:235) ←issues list, default-l 50(src/commands/issues.ts:604)FilteredSearchIssues(graphql/queries/issues.graphql:357) ←issues search, default-l 50(src/commands/issues.ts:638)The arithmetic
#284 measured, against the live API, that each issue selected through
CompleteIssueFieldsprices at ~260 (consistent with4 connections × 50 rows × 1.3). That measurement is what justified loweringprojects read --issues-firstfrom 50 to 25 there — empirically it passes at 35 and fails at 40, i.e. a ceiling around10000/263 ≈ 38issues.Applying the same model to
issues listat its default limit of 50 gives ~13,000 against the 10,000 budget.What needs checking first
The ~260 figure was measured for issues nested under a project, not for issues at the query root. Before any code change, someone with a real workspace should run:
CompleteIssueFields. Note that fragment is shared far more widely than the project fragments were, so this is a cross-domain behaviour change (silent truncation of labels/children/relations per issue) and wants its own measurement pass rather than a copy of the 25s.graphql/queries/projects.graphqlandsrc/services/project-service.tsshould get a footnote saying so, since it currently reads as universal.Either outcome is worth having written down.
Related, same shape
src/commands/issues.ts:1471readsCompleteIssueFields.labels(unbounded, so an implicit 50) and writes the result back as a full-replacementlabelIds. An issue with more than 50 labels would therefore lose labels 51+ onissues update --label-mode add. Unreachable in practice, but it is exactly the read-modify-write hazard #284 moved theprojectsdomain off of (its lean pre-read now fetches 250), so the two domains are now inconsistent. Worth fixing in the same pass.Context
Split out of the review of #284, which deliberately scoped itself to the
projectsdomain. Nothing here regresses because of that PR — this defect predates it.Refs #284
Refs #276
Refs #283