A ticket that reads "combine the workspace and team dropdowns into one selector" sounds like a UI polish item — the kind of change a designer files after using the product for a week. This one wasn't. Underneath the request for a single popover was a real correctness bug: Influxx's Linear integration had been silently under-fetching teams in larger workspaces since the first page of results, with no signal to the user that anything was missing. Fixing the selector meant fixing the data underneath it first.
A Dropdown That Looked Fine and Wasn't
Before this change, Influxx exposed two separate controls for scoping your Linear view: a workspace dropdown and a team dropdown, populated independently. The team dropdown's list came from a single call to Linear's teams API per workspace. For a workspace with a small number of teams, that call returned everything and the dropdown looked complete. For a workspace with more teams than fit in a single response page, it didn't — and there was no error, no truncation notice, nothing in the UI that would tell you a team existed in Linear but wasn't selectable in Influxx.
This is the kind of bug that's almost impossible to catch by inspection. The dropdown renders. It has entries. It responds to clicks. The only way to notice something is wrong is to already know how many teams your workspace has and count what's missing — which is exactly the situation nobody is in when they're just trying to filter a list of issues.
"The dangerous thing about this bug is that it degrades gracefully from the user's point of view. A shorter dropdown doesn't look broken, it looks like a smaller workspace. We only found it because someone filed a report saying a team they knew existed just wasn't there, and when we traced it back it was a plain pagination bug in a call we'd written to only ever look at page one."
— Priya Raghunathan, Senior Engineer, Integrations at ETAPX
Why the Teams API Silently Truncates
Linear's own SDK paginates connection results by default — this isn't unusual behavior on Linear's part, it's the standard shape of a GraphQL connection API. A single request returns a page of results plus a cursor for the next one; callers are expected to keep requesting pages until the API reports there are none left. Influxx's original integration code called the teams endpoint once, took whatever came back on that first page, and used it as the complete team list. In a workspace small enough that every team fit on one page, this worked by coincidence. In a larger workspace, it didn't — and the failure mode was total silence rather than an error, because from the API's perspective the call succeeded exactly as asked.
The same shape of bug wasn't confined to teams. Workflow states, labels, and workspace members are all exposed the same way, as paginated connections, and the original integration read all of them the same single-page way. So the fix wasn't a one-line patch to one endpoint — it was a pattern that had been copied across four different resource types.
Draining the Connection, Not Sampling It
The fix replaces every one of those single-page reads with a loop that keeps requesting pages until the API reports there's nothing left to fetch. Teams, workflow states, labels, and member connections are now each fully drained on sync, rather than trusting whatever happened to come back first. It's a mechanically simple change — the kind of fix that looks almost too small to justify the investigation that led to it — but it's the difference between a team list that's accurate and one that's accurate only below a size threshold nobody had documented or tested against.
The Numbers Behind the Fix
What makes this bug worth writing about isn't complexity, it's scope. One API call per workspace became a loop across four separate paginated connections — teams, workflow states, labels, and members — each drained to completion rather than sampled once. The state surface that sits on top of all that data, by contrast, didn't need to grow at all: the selected workspace is still exactly one of two things, a specific workspace or "all," and the selected team scope is still exactly one of two things, "sticky-all" (no team filter applied) or an explicit set of team IDs. That two-by-two shape was preserved exactly through the rewrite. The bug lived entirely in how completely the underlying data was fetched, not in how the selection state was modeled — which is part of why the fix could ship as a data-layer correction underneath an interface that, from a state-management standpoint, didn't need to change.
- Before: one request per workspace, first page only, four resource types affected (teams, workflow states, labels, members).
- After: full pagination loop per resource type, run until Linear reports no further pages.
- Selection state, unchanged: workspace is "one specific workspace" or "all"; team scope is "sticky-all" or an explicit ID set — never a silently-empty filter that could be confused with zero results.
A Second Bug Hiding in Key Rotation
Fixing the pagination gap surfaced a related problem: what happens when a user upgrades from a team-limited personal API key to a full-access one. Linear's personal API keys can be scoped to specific teams, and a lot of users start with exactly that kind of key before realizing they need broader access. Once the underlying fetch was correct, the natural next question was whether swapping in a better key actually replaced the stale, narrower data — or just sat on top of it until a cache happened to expire.
It didn't, reliably. The old cached team list, along with any in-flight issue, search, and team requests still running against the old key's scope, could persist for the length of the existing cache lifetime even after a full-access key was saved. A user could correctly upgrade their key and still see the old, truncated team list for a stretch of time afterward, with no indication that anything needed a refresh.
Clearing State Before Publishing the Connection
The fix makes key rotation synchronous with cache invalidation. When a full-access key replaces a team-limited one, Influxx now clears the cached team list, cancels or discards in-flight issue, search, and team requests, and drops related metadata — all before it publishes the new connection as successful. The ordering matters: a successful connection can't be reported until the stale state behind it is gone, so there's no window where the UI says "connected" while still quietly serving data fetched under the old, narrower key.
"We treated this as the same category of bug as the pagination issue, even though it's a caching problem and not a fetching problem. Both of them come down to the same failure: the UI believes it has a complete, current picture of your workspace, and it doesn't. Clearing state synchronously, before we tell the user the connection succeeded, closes that gap instead of hoping the cache expires soon enough that nobody notices."
— Priya Raghunathan, Senior Engineer, Integrations at ETAPX
One Selector, Correctly Labeled
With the data layer fixed, the original UI request could actually be built honestly: a single combined scope selector replacing the separate workspace and team dropdowns with one popover. The trigger label adapts to whatever's selected — it can show specific team abbreviations directly when the scope is narrow enough, or collapse to a summary like "All workspaces / 2 teams" when it isn't. Collapsing two controls into one only makes sense once you trust that the list feeding it is complete; shipping the merged selector on top of the old single-page fetch would have just made a partial team list look more authoritative, not less broken.
"I have a workspace with a lot of teams in Linear and I genuinely didn't know some of them weren't showing up in Influxx until I went looking for one specifically. Once it was fixed, the combined selector is honestly the better interface anyway — I don't have to reconcile two dropdowns in my head, the trigger just tells me what I'm looking at."
— Marcus Ito, engineering lead at a logistics software company, Influxx user
Client-Side Filtering Needed Honest Copy
Team filtering in Influxx happens client-side, after issues have already been fetched — it isn't a fresh server-side query scoped to the selected teams each time you change the filter. That's a reasonable design for responsiveness, but it has a real implication once the underlying fetch is capped: if you filter down to a team and see nothing, that can mean the team genuinely has no matching issues, or it can mean the currently fetched, currently cached set of issues just doesn't include any for that team yet. Those are different situations, and the old UI didn't distinguish them.
The copy was updated to say exactly that: the empty state now reads that no fetched or current issues match the selected teams, rather than implying an exhaustive search came back empty. It's a small wording change with an outsized effect on trust — a user who reads "no issues match" as a server-verified fact will draw a very different conclusion than one who understands it as "nothing in what we've loaded so far matches," and only one of those readings is accurate given how the filtering actually works.
"A dropdown that quietly drops teams and an empty state that quietly implies more certainty than it has are the same class of problem — the interface is telling the user something it can't actually back up. Once we saw the pagination bug clearly, we went looking for every other place in the Linear integration where the UI was making a claim the data behind it couldn't support, and the empty-state copy was the next one on the list."
— Sofia Bellweather, VP of Product at ETAPX
Centralizing How You Add Linear Access
The last piece of this change is a new dedicated dialog for the "add Linear access" flow, replacing whatever ad hoc entry points existed before. It centralizes the connection process and, importantly, explains up front the distinction that caused the key-rotation bug in the first place: the difference between a full-access personal API key and a team-limited one, and Linear's own requirement that you be a member of a private team to see its issues at all — a limitation that no key scope or Influxx setting can work around, because it's enforced on Linear's side.
The dialog is also where new helper functions come in: they build workspace-specific deep links straight to a given organization's Linear API-key settings page, so a user upgrading their key lands exactly where they need to be instead of Linear's generic settings screen. When the specific workspace isn't known yet — for instance, before a first connection exists — the helpers fall back to Linear's generic settings URL rather than guessing or failing outright.
- Explains key scope up front: full-access versus team-limited personal API keys, before a user picks one.
- States Linear's own membership rule: you must be a member of a private team to see its issues, independent of what Influxx does.
- Deep-links to the right settings page: workspace-specific when the organization is known, generic fallback when it isn't.
Why This Sequencing Matters
The interesting part of this story isn't the fix itself — draining a paginated API and invalidating a cache synchronously are both well-understood patterns. It's that the request arrived looking like pure UX work, and treating it as pure UX work would have shipped a nicer-looking control sitting on top of the same incomplete data. A merged selector that confidently displays "All workspaces / 2 teams" is worse than two separate, slightly clunkier dropdowns if the "2 teams" is wrong. Getting the sequencing right — fix the fetch, fix the cache invalidation, then simplify the interface — is what turned a cosmetic ticket into a correctness fix that happened to also improve the UI.
Frequently Asked Questions
Did this bug affect every Linear workspace connected to Influxx?
It only affected workspaces with more teams than fit on a single page of Linear's teams API response. Smaller workspaces where every team fit in one page were never missing anything, which is part of why the bug went unnoticed for a while.
Was this limited to teams, or did other Linear data have the same issue?
The same single-page pattern existed for workflow states, labels, and workspace members, since all four are paginated connections in Linear's API. The fix applies the same drain-until-exhausted loop to all four.
If I already connected Linear with a team-limited key, do I need to reconnect?
You need to replace the key with a full-access one through the connection flow; when you do, Influxx now synchronously clears the cached team list and any in-flight requests before confirming the new connection, so you shouldn't see stale, narrower data lingering afterward.
Why does the combined selector sometimes show team abbreviations and sometimes a summary like "All workspaces / 2 teams"?
The trigger label adapts to how specific your current scope is — narrow selections show the actual team abbreviations, broader selections collapse to a count-based summary so the label stays readable.
Why does the empty state say "no fetched/current issues match" instead of just "no issues"?
Because team filtering happens client-side against issues already fetched, not a fresh server-side query. The wording makes clear you're looking at a filter over what's currently loaded, not a guaranteed-exhaustive search of the team's entire issue history.
Can I see a private Linear team's issues in Influxx if I'm not a member of it in Linear?
No — that's a restriction enforced by Linear itself, not by Influxx, and the new "add Linear access" dialog states it explicitly so it isn't mistaken for a bug or a missing permission on the Influxx side.
Does the new selector change how workspace and team scope are stored or synced?
No. The underlying state model — one specific workspace or "all," and either "sticky-all" team scope or an explicit set of team IDs — was preserved exactly; only the fetch completeness underneath it and the interface presenting it changed.
The lesson here isn't "watch out for pagination" — every engineer already knows connections paginate. It's that a UI simplification request is often the first symptom of a data-completeness problem, not a separable cosmetic task, and the two have to be fixed in that order or the simpler interface just makes the wrong data easier to trust.

