mirror of
https://github.com/qwibitai/nanoclaw.git
synced 2026-06-04 10:14:47 +08:00
fix: recover from stale Claude Code session IDs instead of retrying infinitely
When Claude Code exits with code 1 during a session resume, the group's session ID is now cleared from the database and the query is retried with a fresh session. This prevents the infinite retry loop that occurred when a stale/corrupt session ID was stored in SQLite. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -526,6 +526,10 @@ export function setSession(groupFolder: string, sessionId: string): void {
|
||||
).run(groupFolder, sessionId);
|
||||
}
|
||||
|
||||
export function deleteSession(groupFolder: string): void {
|
||||
db.prepare('DELETE FROM sessions WHERE group_folder = ?').run(groupFolder);
|
||||
}
|
||||
|
||||
export function getAllSessions(): Record<string, string> {
|
||||
const rows = db
|
||||
.prepare('SELECT group_folder, session_id FROM sessions')
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
getAllChats,
|
||||
getAllRegisteredGroups,
|
||||
getAllSessions,
|
||||
deleteSession,
|
||||
getAllTasks,
|
||||
getMessagesSince,
|
||||
getNewMessages,
|
||||
@@ -355,6 +356,51 @@ async function runAgent(
|
||||
}
|
||||
|
||||
if (output.status === 'error') {
|
||||
// Detect stale/corrupt session: container failed while resuming an existing session.
|
||||
// Clear the session and retry once with a fresh session to avoid infinite retry loops.
|
||||
if (sessionId) {
|
||||
logger.warn(
|
||||
{ group: group.name, staleSessionId: sessionId, error: output.error },
|
||||
'Container failed with existing session — clearing stale session and retrying with fresh session',
|
||||
);
|
||||
delete sessions[group.folder];
|
||||
deleteSession(group.folder);
|
||||
|
||||
const freshOutput = await runContainerAgent(
|
||||
group,
|
||||
{
|
||||
prompt,
|
||||
sessionId: undefined,
|
||||
groupFolder: group.folder,
|
||||
chatJid,
|
||||
isMain,
|
||||
assistantName: ASSISTANT_NAME,
|
||||
},
|
||||
(proc, containerName) =>
|
||||
queue.registerProcess(chatJid, proc, containerName, group.folder),
|
||||
wrappedOnOutput,
|
||||
);
|
||||
|
||||
if (freshOutput.newSessionId) {
|
||||
sessions[group.folder] = freshOutput.newSessionId;
|
||||
setSession(group.folder, freshOutput.newSessionId);
|
||||
}
|
||||
|
||||
if (freshOutput.status === 'error') {
|
||||
logger.error(
|
||||
{ group: group.name, error: freshOutput.error },
|
||||
'Container agent error on fresh session retry',
|
||||
);
|
||||
return 'error';
|
||||
}
|
||||
|
||||
logger.info(
|
||||
{ group: group.name, newSessionId: freshOutput.newSessionId },
|
||||
'Fresh session retry succeeded',
|
||||
);
|
||||
return 'success';
|
||||
}
|
||||
|
||||
logger.error(
|
||||
{ group: group.name, error: output.error },
|
||||
'Container agent error',
|
||||
|
||||
Reference in New Issue
Block a user