MoonshotAI / MoonshotAI/kimi-code

Restored session permanently loses tool/subagent access when its persisted runtime binding is stale (acp-runtime-after-reap)

Open
#3,562 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

Bug

A session whose persisted agent runtime binding references a runtime that the current process never registers becomes permanently unable to execute tools or spawn subagents after being restored. Every tool call and subagent spawn fails with:

runtime acp:session_<id> does not exist in workspace <id>

The agent still converses (model calls need no runtime), but cannot act. Restarting turns or re-seeding does not help — only creating a brand-new session escapes.

Root cause

AgentRuntimeBindingService's restore hook (packages/agent-core-v2/src/agent/runtimeBinding/runtimeBindingService.ts) replays a persisted {workspaceId, runtimeId} binding back into state without checking that the runtime exists. RuntimeRegistry is purely in-memory per process. So when a session that was previously driven via kimi acp (binding persisted as acp:<sessionId> by bindSessionRuntime) is later resumed in a host that never registers ACP runtimes — the TUI, kap-server, or headless kimi -S <id> -p — the restored binding points at a runtime id that will never exist in that process:

  • runtime-gated tools (Bash, Read, Write, …) stay deactivated because availability probes return false, and
  • IAgentRuntimeService.acquire() throws runtime.not_found for every subagent spawn and any tool that does run.

Note that validating the binding at restore time is not a correct fix: in the healthy ACP flow, agent scope restore runs before bindSessionRuntime registers the session's ACP runtime (wireSession in packages/acp-server/src/server.ts), so restore-time acquisition would break the normal resume path.

Reproduction

  1. Create a session over ACP (kimi acp + session/new), so the main agent's binding persists as acp:<sessionId>.
  2. Resume the same session in a non-ACP host, e.g. headless: kimi -S <sessionId> -p "…".
  3. Ask the agent to spawn a subagent → fails with runtime acp:session_<id> does not exist in workspace <id>; runtime-gated tools are missing from the toolset.

Proposed fix

Heal lazily at the point of use: in AgentRuntimeService.inspect()/acquire()/isAvailable() (packages/agent-core-v2/src/agent/runtimeBinding/agentRuntime.ts), catch RuntimeError with code runtime.not_found, rebind the agent to the always-present local runtime via IAgentRuntimeBindingService.set() (which persists the durable RuntimeSetBinding event), and retry once. Runtimes that are registered but unavailable (disconnected/draining) never trigger the heal; if the fallback is also missing, the original error is rethrown with the fallback failure attached as cause.

PR with the fix + unit tests follows, linked to this issue.

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

Start in packages/agent-core-v2/src/agent/runtimeBinding/agentRuntime.ts and trace inspect(), acquire(), and isAvailable() against AgentRuntimeBindingService.set(). Review the restore hook in packages/agent-core-v2/src/agent/runtimeBinding/runtimeBindingService.ts and ACP registration through wireSession in packages/acp-server/src/server.ts. Done means stale runtime.not_found bindings heal to local without healing registered-but-unavailable runtimes, and unit tests cover the retry and fallback error paths.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.