|
| 1 | +--- |
| 2 | +title: "Search & Add's invokes never reach the workspace — the pane hangs at 'searching…' while every backend rung is green" |
| 3 | +lede: "The 🔍 term-search pane stalls forever with a one-chip palette, yet SearXNG answers directly, search.fire answers over NATS, and the org card loads fine over the same workspace — the frame dies somewhere in the client transport, and tonight's commits are exonerated." |
| 4 | +date_created: 2026-07-28 |
| 5 | +date_modified: 2026-07-28 |
| 6 | +authors: |
| 7 | + - Michael Staton |
| 8 | +augmented_with: |
| 9 | + - Claude Code on Claude Fable 5 |
| 10 | +semantic_version: 0.0.0.1 |
| 11 | +tags: |
| 12 | + - Issue |
| 13 | + - Augment-It |
| 14 | + - Search-And-Add |
| 15 | + - Workspace-Transport |
| 16 | + - Debugging-Journey |
| 17 | +status: Active |
| 18 | +--- |
| 19 | + |
| 20 | +# Search & Add invokes never reach the workspace |
| 21 | + |
| 22 | +## Symptom (operator report, 2026-07-28 ~02:00) |
| 23 | + |
| 24 | +"SearXNG is down / search is no longer working." In the UI: open any org |
| 25 | +card → 🔍 on a list → the Search & Add pane opens, seeds its term, and |
| 26 | +hangs at **"searching…" (button disabled) forever**. The provider palette |
| 27 | +shows only "auto" — the connector chips never load. No error ever |
| 28 | +surfaces. Reproduced twice, including on a fresh page load against a |
| 29 | +freshly restarted stack. |
| 30 | + |
| 31 | +## What is PROVEN healthy (all verified live during the same session) |
| 32 | + |
| 33 | +- **SearXNG**: direct HTTP `/search?format=json` → 200 with results. |
| 34 | +- **search.fire over NATS**: `ok, provider: searxng, 10 results` — twice, |
| 35 | + including post-restart with a team query returning |
| 36 | + `carnegiefoundation.org/our-team` as the first hit. |
| 37 | +- **connectors.inventory over NATS**: 6 connectors, correct statuses. |
| 38 | +- **The same workspace hop for OTHER verbs**: the org card fully loads |
| 39 | + (organization.detail / relations / affiliations) over `ws://…:3001/ws` |
| 40 | + in the same page, same session. |
| 41 | +- **The queue path**: 🤖 crawls submit and run (`crawl started |
| 42 | + carnegie-foundation` in the same window); `search.submit` jobs land in |
| 43 | + the rail. |
| 44 | + |
| 45 | +## The load-bearing negative |
| 46 | + |
| 47 | +When the pane fires, **neither workspace-service nor social-search logs |
| 48 | +anything** — and social-search's `search.fire` log line (which my direct |
| 49 | +NATS probe produces every time) never appears. `ws.ts`'s invoke handler |
| 50 | +always replies (ok or error; dispatch has a 30s NATS ceiling), so a frame |
| 51 | +that reached the server would produce SOMETHING within 30s. The pane |
| 52 | +hangs for minutes. **Conclusion: the invoke frame never reaches ws.ts — |
| 53 | +it dies in the client-side transport** (`packages/workspace/src/ |
| 54 | +transport.ts` queue/claim machinery), or is sent on a socket the server |
| 55 | +never associates with a reply path. |
| 56 | + |
| 57 | +Context that may matter: workspace logs show heavy ws connect/close churn |
| 58 | +(sessions bouncing 5→11) — every remote holds its own socket (NO |
| 59 | +module-federation singleton, per shell/rsbuild.config.ts's deliberate |
| 60 | +no-shared-block decision), and the stack had been restarted mid-session. |
| 61 | + |
| 62 | +## What did NOT break it |
| 63 | + |
| 64 | +- **Tonight's commits (2026-07-27/28)**: none touch search-and-add, |
| 65 | + transport.ts, ws.ts, social-search, or the SearXNG config. The |
| 66 | + capabilities.ts changes were purely additive (verified: zero deleted |
| 67 | + lines). The crawl-budget change affects Anthropic crawls only. |
| 68 | +- **SearXNG itself**: healthy, though upstream engines degrade over long |
| 69 | + uptimes — the 11-day-old container had accumulated engine suspensions |
| 70 | + (`SearxEngineAccessDeniedException: HTTP error 403, suspended_time= |
| 71 | + 86400`, qwant JSON failures). `docker compose restart searxng` clears |
| 72 | + them (suspensions are in-memory). Worth knowing as routine hygiene, |
| 73 | + but NOT this bug. |
| 74 | + |
| 75 | +## Suspect window |
| 76 | + |
| 77 | +Everything in the failing path was last modified **2026-07-24**: |
| 78 | + |
| 79 | +- `56191ce` — fix(workspace, transport): invokes survive reconnects — the |
| 80 | + claim protocol (transport.ts + ws.ts) |
| 81 | +- `f61a5b3` — feat: searches become async jobs — the queue rail |
| 82 | + (search-and-add + ws.ts) |
| 83 | +- `3ca925d` — fix(search-and-add): auto-fire waits for the workspace |
| 84 | + socket (the mount-time race this pane already had once) |
| 85 | + |
| 86 | +Hypothesis space, narrowed: the pane's TWO mount-time invokes |
| 87 | +(`connectors.inventory` for the palette + the auto-fired `search.fire`) |
| 88 | +both hang, while later same-socket traffic elsewhere works — so suspect |
| 89 | +the mount-time path: frames queued pre-OPEN whose flush-on-open or |
| 90 | +claim-on-reconnect leg loses them silently under socket churn |
| 91 | +(`pendingAutoFire` waits for `status === 'open'`, but the status store |
| 92 | +and the socket the sendQueue flushes to may disagree across reconnect). |
| 93 | + |
| 94 | +## Repro |
| 95 | + |
| 96 | +1. `./scripts/dev.sh up`, open `localhost:3100`, Flows → Augment from DB |
| 97 | + (then click the step bubble — see the KNOWN separate issue |
| 98 | + [[Flow-Switch-Doesnt-Surface-The-New-Flows-Stage-Step-Bubble-Click-Required]]). |
| 99 | +2. Search to any org → 🔍 on Identity & social links. |
| 100 | +3. Pane opens, term seeds, "searching…" forever; palette = "auto" only. |
| 101 | + |
| 102 | +## Next probes (for the fix session) |
| 103 | + |
| 104 | +1. Instrument `transport.ts`: console.debug on enqueue / flush / send / |
| 105 | + claim, with frame ids — watch where the two mount invokes stall. |
| 106 | +2. Log invoke receipt (capability + id) at the top of ws.ts's invoke |
| 107 | + branch — turns "never reached the server" from inference into fact. |
| 108 | +3. Check whether fire()'s promise rejection path can be swallowed when |
| 109 | + the component re-mounts mid-invoke (zombie pane holding the pending |
| 110 | + promise while a fresh instance renders the stuck button). |
| 111 | +4. Client-side deadline: a62d3dc gave CRAWL invokes a client deadline — |
| 112 | + ordinary invokes appear to have none, which is why this hangs forever |
| 113 | + instead of erroring. A default client timeout would at least fail |
| 114 | + loud. |
| 115 | + |
| 116 | +## Workarounds meanwhile |
| 117 | + |
| 118 | +- The 🤖 queue path (search.submit → search-results rail) works. |
| 119 | +- `node scripts/prove-augment-from-db-capabilities.mjs`-style direct NATS |
| 120 | + fires work for ad-hoc searches. |
| 121 | +- Restart SearXNG periodically to shed engine suspensions: |
| 122 | + `docker compose restart searxng`. |
| 123 | + |
| 124 | +## See also |
| 125 | + |
| 126 | +- `changelog/2026-07-24_07_Searches-Become-Async-Jobs…` — the rework that |
| 127 | + landed the suspect commits. |
| 128 | +- [[Flow-Switch-Doesnt-Surface-The-New-Flows-Stage-Step-Bubble-Click-Required]] — |
| 129 | + the separate, known "Augment from DB looks gone after reload" symptom |
| 130 | + hit in the same session. |
0 commit comments