MoonshotAI / MoonshotAI/kimi-code
web: transcript baseline GET times out at 30s on large live sessions (200 + parse phase), session renders empty and retries forever
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 7.5k
- Forks
- 1.2k
- Avg merge
- 11h 53m
- Merged PRs (30d)
- 350
Description
What version of Kimi Code is running?
2.0.0 (kimi --version). First seen on 0.42.0; reproduced unchanged on 2.0.0. The analysis below is against main @ 1fddc16e3.
Which open platform/subscription were you using?
Moonshot AI open platform (api.moonshot.ai)
Which model were you using?
kimi-k3 (moonshot-ai/kimi-k3)
What platform is your computer?
Microsoft Windows NT 10.0.26200.0 x64 (Windows 11 Home)
What issue are you seeing?
In kimi web, some sessions never render their content. Opening the session shows nothing from the transcript and the UI falls back to the "new session" view, even though the agent is clearly still running (the working/loading indicator keeps animating). So I cannot see anything the agent is doing in that session.
The browser console logs this on every retry (attempt counter keeps climbing, this one is attempt 15):
[kimi-code] transcript baseline retry failed
Object { sessionId: "session_xxxxx", attempt: 15, err: DaemonNetworkError }
err: DaemonNetworkError: Failed to parse JSON response from GET /sessions/session_xxxxx/transcript
Full error object:
{
"sessionId": "session_xxxxx",
"attempt": 15,
"err": {
"cause": {},
"method": "GET",
"path": "/sessions/session_xxxxx/transcript",
"url": "http://xxxx/api/v1/sessions/session_xxxxx/transcript?agent_id=main&page_size=10",
"requestId": "xxxxxx",
"phase": "parse",
"timeoutMs": 30000,
"status": 200,
"statusText": "OK",
"contentType": "application/json; charset=utf-8",
"timestamp": 179966783,
"durationMs": 30000,
"name": "DaemonNetworkError"
}
}
Note the combination: status: 200, contentType: application/json, phase: "parse", durationMs: 30000 == timeoutMs, and an empty cause. The server did answer with 200, but the client gave up exactly at the 30 s budget while reading/parsing the body, so this is not a "server is down" case.
What steps can reproduce the bug?
- Start
kimi weband open the UI in the browser. - Have a long-running / large session (in my case the agent works for a long time and produces a lot of tool output). The session is still actively running when I open it.
- Open that session from the sidebar (or reload the tab while on it).
- Nothing from the transcript is rendered; the UI shows the "new session" area, while the working indicator shows the agent is still busy.
- Console shows the
transcript baseline retry failederror above, and it keeps retrying forever with the same failure (attemptincreases; I have seen 15+).
Other, smaller sessions in the same server open fine. Session id available on request (redacted above as session_xxxxx).
What is the expected behavior?
The session transcript should load (at least the requested page of 10 turns) and I should be able to follow what the agent is doing. If the first page cannot be loaded within the timeout, the UI should say so explicitly and keep the session context (not silently fall back to the new-session view), and the retries should have a chance of succeeding rather than hitting the same wall every time.
Additional information
I looked at the code in this repo (main @ 1fddc16e3) and the shipped web bundle (apps/kimi-code/dist-web/assets/index-DusVyqlT.js) to narrow it down:
- Client side, single 30 s budget for headers + body. The generic REST
request()in the web bundle creates oneAbortSignalwithtimeoutMs = 30000and passes it tofetch(). The same signal is still live while it doesawait response.text()followed byJSON.parse(...). If the body has not been fully received within 30 s from the start of the request, the abort fires insidetext(), and the resultingAbortErroris wrapped asphase: "parse"/Failed to parse JSON response. That matches every field in the error above (status 200,durationMs === timeoutMs,cause: {}becauseDOMExceptionserializes to an empty object). - Server side,
page_sizeonly boundsitems.GET /sessions/{session_id}/transcript(packages/kap-server/src/routes/transcript.ts) paginates the turns, but for a live session it also serializes the full, unpaginatedtasks,interactions,attachments,todos,prompts,metaandagentscollections in the same envelope. The 10 turns themselves can also carry very large tool outputs. For a big session the body is therefore large regardless ofpage_size=10. There is no response compression in kap-server either. Before responding, the live path also awaitswhenReady()andensureAgentHistory()(wire-record backfill), which is time spent inside the same 30 s budget. - Retry loop cannot recover. The transcript pool retries the baseline load with
min(attempt * 2000, 15000)ms backoff, indefinitely. Only the first failure is surfaced (onBaselineError→pushOperationFailure("loadSessionTranscript")); later ones only logtranscript baseline retry failed. Every retry issues exactly the same request with the same 30 s cap, so once the response is too big/slow to fit, it fails forever and the UI stays empty.
Possibly related:
- #3592 ("上下文很长的对话经常出现打不开(超时)") — same
loadSessionTranscriptfailure, reported as "cannot connect to Kimi server", also on long sessions. - #3519 (opening an actively streaming session hangs at "Loading…") — similar trigger (session live at open time), but that one is a renderer loop; here the request itself times out and the page renders empty.
- #3815 (long-session performance audit).
Ideas that would address it (happy to test a build):
- Use a separate, longer read timeout for the transcript baseline (or an idle timeout on body progress) instead of one total 30 s budget for the whole request.
- Bound the non-
itemscollections in the transcript response (paginate / lazy-loadinteractions,attachments,prompts, …) sopage_sizeactually bounds the payload; or enable compression for/api/v1JSON responses. - On repeated baseline failure, keep the session view with an explicit error/retry instead of the new-session fallback, and make the retry loop stop or back off further after N attempts.
Contribution
- I am willing to submit a PR for this bug fix myself (please wait for maintainer approval in this issue first)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with packages/kap-server/src/routes/transcript.ts and the web client's generic REST request, then trace the transcript pool's loadSessionTranscript baseline retry path. Reproduce with a large live session and inspect the response timing and payload size. Done means the transcript can load or present an explicit retained-session error, without retrying indefinitely against the same timeout.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, backend, performance, web-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100