MoonshotAI / MoonshotAI/kimi-code

ACP: session/prompt never returns after terminal LLM failure on resumed session

Open
#2,037 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
7.5k
Forks
1.2k
Avg merge
11h 53m
Merged PRs (30d)
350

Description

Description

When a session/prompt request fails with a terminal LLM error on a resumed session, the ACP server never answers the request: no PromptResponse, no JSON-RPC error, no session/update explaining the failure. The client waits forever and the user just sees a spinner.

Environment

  • kimi-code 0.28.1 (npm @moonshot-ai/kimi-code), macOS arm64
  • Client: helios-kanban ACP harness (session/load + session/prompt per turn, process killed after each turn)

Evidence

  1. A long ACP session (84 steps) ended normally from the client's perspective — the final assistant text was streamed and displayed.

  2. However, the last step was persisted incompletely in ~/.kimi-code/sessions/<ws>/<session>/agents/main/wire.jsonl: only step.begin and a single empty content.part ({"type":"think","think":""}); no text parts and no step.end — even though logs/kimi-code.log records llm response turnStep=0/84 ... outputTokens=478. Same torn-record pattern as #1404; here the ACP client terminated the process right after the turn completed, so the final step never got flushed.

  3. The next day, a follow-up via session/load + session/prompt. kimi-code.log shows:

    2026-07-22T01:58:08.961Z INFO  session resume  app_version=0.28.1
    2026-07-22T01:58:11.496Z INFO  llm request  turnStep=1.1
    2026-07-22T01:58:12.255Z WARN  llm request failed  turnStep=1.1 attempt=1/10 model=k3 errorName=APIStatusError errorMessage="400 the message at position 202 with role 'assistant' must not be empty" statusCode=400
    

    (the k3 provider's wording of the #1404 error)

  4. After that single WARN: nothing. No further retry attempts, no llm response, no ACP traffic. The pending session/prompt request was still unanswered 9 minutes later; the process stayed alive but silent.

Expected

A terminal LLM failure must resolve the pending session/prompt request — ideally with a JSON-RPC error response, or at minimum a session/update carrying the error followed by a PromptResponse — so ACP clients can surface the failure instead of hanging indefinitely.

Separately, #1882 will make this specific trigger recoverable by dropping the empty assistant tail on resume; but any other terminal LLM failure would still hang the client, so the protocol-level fix is needed independently.

Related

  • #1404 — empty assistant message after interrupted turn causes 400 on resume (root cause of the 400 seen here)
  • #1882 — open fix PR for the resume-side repair

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Trace the ACP handling for session/prompt after a terminal LLM failure, using the session/load and session/prompt flow described here. Inspect wire.jsonl and kimi-code.log behavior around the missing response and compare the expected PromptResponse, JSON-RPC error, or session/update path. Done means every terminal failure resolves the pending request and gives the client an actionable error instead of hanging.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.