Skip to content

fix(stdio): bound embedQuery and fast-fail during background reindex#165

Merged
aeneasr merged 4 commits into
mainfrom
fix-hanging-followup
May 20, 2026
Merged

fix(stdio): bound embedQuery and fast-fail during background reindex#165
aeneasr merged 4 commits into
mainfrom
fix-hanging-followup

Conversation

@aeneasr
Copy link
Copy Markdown
Member

@aeneasr aeneasr commented May 20, 2026

Summary

Hardens the fix-hanging short-circuit (merged in PR #161-ish) with three follow-ups uncovered during review:

  • Bound embedQuery (defense-in-depth) — Mirror the existing defaultSearchTimeout on idx.Search. Without an outer bound, the embedder's 10-minute HTTP client timeout surfaces as an effective hang in Claude Code on any embedder pathology (cold-start GPU, network drop, server crash mid-request). New defaultEmbedTimeout = 20s.
  • Fast-fail embed + preserve stale results — The merged fix returned warning-only whenever StaleWarning was set, throwing away results from the (still-readable) DB. Now we give the embed a short window (defaultStaleEmbedTimeout = 3s); if it succeeds, return stale-but-real results plus the warning; if it times out, fall back to warning-only.
  • Drop brittle "10 tool calls" advice — That count is wildly under-counted for large repos like cloud where a first-time index runs 10+ minutes. New wording points at grep/glob/find and notes that big repos take longer. Also consolidated four duplicate copies into a single staleIndexWarning constant.

Test plan

  • TestHandleSemanticSearch_EmbedQueryBounded — defense-in-depth path: blocking embedder, no StaleWarning, returns with embed query error within ~500ms (not 10 minutes)
  • TestHandleSemanticSearch_StaleWarningFastEmbedReturnsStaleResults — fast embed + flock held: returns stale results from the DB plus the warning
  • TestHandleSemanticSearch_StaleWarningShortCircuits — updated for new fast-fail behavior (embed is attempted, gets cancelled within staleEmbedTimeout)
  • TestStaleIndexWarning_NoBrittleToolCallCount — asserts the new wording
  • go test ./... PASS (~2 min)
  • golangci-lint run ./... zero issues
  • go vet ./... clean
  • End-to-end against the original cloud repo reproduction: lumen purge ~/workspace/go/cloud && lumen index ~/workspace/go/cloud (background), then semantic_search via stdio while indexer holds the flock — debug.log shows stale embed fast-fail: returning warning-only with timeout=3s and the call returns immediately. No 10-minute hang.

🤖 Generated with Claude Code

aeneasr and others added 4 commits May 20, 2026 13:24
The "Index is being updated in the background..." message was duplicated
verbatim in four places. Extract to a single staleIndexWarning constant
so future wording changes are a one-line edit.

No behavior change.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Initial indexing of large repos (e.g. the cloud monorepo) can run for
10+ minutes, easily spanning more than 10 tool calls. The old advice
"Use standard tools for the next 10 tool calls" was therefore wildly
under-counted and confusing. Replace with a concrete fallback hint
(grep/glob/find) and a more accurate duration.

The "Index is being updated in the background" prefix is preserved so
existing callers and tests that match on it continue to work.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…epth

The underlying embedder HTTP client has a 10-minute timeout; without an
outer bound, any embedder pathology (cold-start GPU, network drop, server
crash mid-request) surfaces as a hang in Claude Code. Mirror the existing
defaultSearchTimeout on idx.Search by wrapping embedQuery in a 20s
context.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
… results

Replace the unconditional warning-only short-circuit with a deadline-aware
embed attempt:
- StaleWarning set: bound embed at defaultStaleEmbedTimeout (3s). On
  success, return stale-but-real results from the existing DB plus the
  warning; on ctx timeout/cancel, fall back to warning-only.
- StaleWarning empty: defense-in-depth bound at defaultEmbedTimeout (20s).

This is strictly better UX than warning-only when the embedding backend
isn't actually saturated, while still avoiding the 10-minute hang when it
is.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 2026

Warning

Rate limit exceeded

@aeneasr has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 28 minutes and 34 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 49d50e8d-33a7-4056-8eb7-40ee04c768c5

📥 Commits

Reviewing files that changed from the base of the PR and between 89555d0 and afbc6c9.

📒 Files selected for processing (3)
  • cmd/stdio.go
  • cmd/stdio_concurrency_test.go
  • cmd/stdio_test.go
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-hanging-followup

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@aeneasr aeneasr enabled auto-merge (squash) May 20, 2026 12:02
@aeneasr aeneasr merged commit d7782cf into main May 20, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant