Skip to content

CLEAN-100: bound every LightRAG call, say so when it hangs - #92

Open
mykyta-torbynskyi wants to merge 2 commits into
mainfrom
fix/CLEAN-100-lightrag-call-timeouts
Open

mykyta-torbynskyi wants to merge 2 commits into
mainfrom
fix/CLEAN-100-lightrag-call-timeouts

Conversation

@mykyta-torbynskyi

@mykyta-torbynskyi mykyta-torbynskyi commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Jira: CLEAN-100. Two commits.

Incident (Mazda dev, 2026-09-18 12:32 UTC). LightRAG's Postgres pod was moved to another node. The data survived (PVC), Postgres was back within a minute, but LightRAG kept a pool of connections to the pod that was gone: /health and /documents/pipeline_status answered in 0.5 s, everything that touches the database hung (/documents did not answer in 120 s), its log went silent. It did not recover on its own; deleting the LightRAG pod fixed it (a query went from "never" to 17 s). For an hour every query_knowledge hung until the MCP client's own 60 s limit and surfaced as MCP error -32001: Request timed out, which sent people looking at MCP. The API log had no line of ours about it.

Gaps. None of LightragHttpClient's calls except /health had a timeout. The index reconciler awaits them inside its running lock, so one hung listDocuments and no pass would ever run again until the API restarted. An Index run against such an instance would upload source after source into the same hang.

Change.

  • Every LightRAG call runs under a deadline (bounded): 30 s for status reads, 50 s for a query (under the MCP client's 60 s on purpose), 60 s for the graph, two minutes for an upload, five for a delete. A cut-short exchange is a LightragTimeoutError (a LightragClientError, status 504, names the path and the wait); anything else passes through untouched. The message reads ... timed out after N s, which the retry classifier from CLEAN-96 already treats as transient.
  • query_knowledge: a base that does not answer is reported to the agent in words ("is not answering right now ... most likely restarting ... try again in a few minutes") instead of a transport error, and the per-base failure is now logged (query_knowledge failed for agent=... knowledge=...). It used to be folded into a normal result without a log line.
  • Source gateway: when the document listing times out, that instance is left alone for the run or reconcile pass: no uploads, no per-source status reads, no row written, due retries stay due. It probes /health once and logs one error line naming the state: answers /health but /documents timed out after 30 s: its database connections are most likely stuck ... Restart the LightRAG pod. That is the line to alert on. Any other listing failure stays non-fatal, as before.
  • reins README: a section on this state and how Ranch reacts.

Out of scope: restarting LightRAG from Ranch; a liveness probe that touches the database in the chart (gitops).

Verified: bun run build, generate:swagger boots, bunx jest src/slices/reins: 20 suites, 225 tests. New specs: the client against a fetch that never resolves on fake timers (gives up at 50 s and not at 49, bounds the reads, aborts the socket, leaves no timer behind, passes other failures through), the tool's wording, the gateway stepping aside in an index run, a reconcile pass and a retry pass.

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.

2 participants