fix: throw resourceNotFound when loadSession fails to resume#363
Conversation
When `loadSession` calls `createSession` with `{ resume: sessionId }` and
the CLI subprocess can't find persisted session data on disk (no .jsonl
file), the subprocess exits immediately. This causes `createSession` to
reject with a generic -32603 "Query closed before response received" error.
Callers like acpx check for resource-not-found errors (-32001/-32002) to
decide whether to fall back to `session/new`. The generic -32603 bypasses
this check, causing the entire turn to fail instead of gracefully creating
a new session.
This commonly happens when `session/new` creates an ACP session ID but the
CLI subprocess exits before writing any session data (because there was no
prompt to process). The subsequent `session/prompt` spawns a new subprocess
and tries `session/load` to resume — but there's nothing to resume from.
Fix: wrap the `createSession({ resume })` call in try/catch and re-throw as
`RequestError.resourceNotFound()` (code -32002) so callers can handle it
with their existing fallback logic.
Fixes zed-industries#338
Closes zed-industries#361
Closes zed-industries#362
|
We require contributors to sign our Contributor License Agreement, and we don't have @maskedband1t on file. You can sign our CLA at https://zed.dev/cla. Once you've signed, post a comment here that says '@cla-bot check'. |
|
@cla-bot check |
|
The cla-bot has been summoned, and re-checked this pull request! |
|
Good fix — confirmed this resolves the The gap
// src/acp-agent.ts — unstable_resumeSession() (current)
async unstable_resumeSession(params: ResumeSessionRequest): Promise<SessionResponse> {
const response = await this.createSession( // ← unguarded, same as the pre-fix loadSession
{ cwd: params.cwd, mcpServers: params.mcpServers ?? [], _meta: params._meta },
{ resume: params.sessionId },
);
// ...
}If the Suggested addition async unstable_resumeSession(params: ResumeSessionRequest): Promise<SessionResponse> {
- const response = await this.createSession(
- { cwd: params.cwd, mcpServers: params.mcpServers ?? [], _meta: params._meta },
- { resume: params.sessionId },
- );
+ let response;
+ try {
+ response = await this.createSession(
+ { cwd: params.cwd, mcpServers: params.mcpServers ?? [], _meta: params._meta },
+ { resume: params.sessionId },
+ );
+ } catch {
+ throw RequestError.resourceNotFound(params.sessionId);
+ }
setTimeout(() => {
this.sendAvailableCommandsUpdate(response.sessionId);
}, 0);
return response;
}VerificationWe independently reproduced the issue and confirmed both code paths are reachable. SDK debug logs show: The Claude Code subprocess exits before any MCP servers connect, and the error propagates as Patching both methods resolves the issue completely — would it make sense to extend this PR to cover |
|
Thanks I pushed this into createSession as it happens at the initialize phase if we have a resume param |
Summary
loadSessioncallscreateSession({ resume: sessionId })and the CLI subprocess can't find persisted session data (no.jsonlfile), the subprocess exits immediately andcreateSessionrejects with a generic-32603("Query closed before response received")-32001/-32002(resource not found) to fall back tosession/new— the generic-32603bypasses this, causing the turn to fail entirelysession/newcreates an ACP session but the subprocess exits before writing session data (no prompt to process), thensession/prompttriessession/loadto resume a session that was never persistedFix
Wrap the
createSession({ resume })call inloadSession()with try/catch and re-throw asRequestError.resourceNotFound()(code-32002). This lets callers handle it with their existing fallback logic.Verification
Confirmed working in production with the OpenClaw gateway + acpx integration. Before the fix, all ACP tasks failed silently. After patching both this code path and acpx's
shouldFallbackToNewSession()(openclaw/acpx#30), sessions fall back tosession/newcorrectly.Fixes #338
Closes #361
Closes #362