BigPizzaV3/CodexPlusPlus · error · Error
后台整理会话已失效,已完成批次仍保留;点击继续可重新处理本批
Error message
后台整理会话已失效,已完成批次仍保留;点击继续可重新处理本批
What it means
During the polling loop, nativeSideChat re-fetches the side conversation each second. If manager.getConversation(session.sideId) returns undefined, the side conversation vanished from the manager (deleted, cleaned up, or app state reset). Completed batches are preserved in the session, and clicking continue will reprocess the current batch.
Solutions
- Click 继续 to create a fresh side conversation and reprocess the current batch; earlier completed batches are kept.
- Avoid closing/reloading Codex while a native-mode organize is running, since ephemeral side conversations do not survive restarts.
- If batches fail repeatedly, switch to external API mode which is restart-resilient.
- Check whether an extension/app cleanup feature deletes ephemeral tasks and disable it.
Example fix
// before
if(!conversation)throw Error('后台整理会话已失效,已完成批次仍保留;点击继续可重新处理本批');
// after
if(!conversation){
Object.assign(session,{sideId:null,turnId:null,phase:'ready'});await save();
return nativeSideChat(threadId,prompt,onProgress,signal,{...options,session}); // auto-recreate
} Defensive patterns
Strategy: fallback
Validate before calling
const conversation = manager.getConversation(session.sideId); if (!conversation) recreateSideConversationAndReprocessBatch();
Type guard
const sideExists = (manager, sideId) => Boolean(sideId && manager.getConversation(sideId));
Try / catch
try { await pollTurn(); } catch (e) { if (e.message.includes('会话已失效')) { resetSideSession(); await nativeSideChat(...); } else throw e; } Prevention
- Recreate the side conversation automatically when it disappears and reprocess only the current batch.
- Do not close/reload Codex during native-mode organizing (ephemeral side tasks are not persisted).
- Persist completed batch results incrementally so restarts lose at most one batch.
When it happens
Trigger: Polling after session.sideId was set, but the conversation registry no longer contains it — side conversation garbage-collected, Codex reloaded and dropped ephemeral conversations, or state desync.
Common situations: User closed/reopened Codex mid-organize (ephemeral conversations are not persisted); an app cleanup pruned the ephemeral side task; manager cache invalidated.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19).
Data as JSON: /api/errors/869c1d698c49caf8.
Report an issue: GitHub.
Appendix: source
Thrown at tools/conversation-canvas/public/canvas.user.js:608
if(session.requestId===requestId&&session.phase==='submitting'&&!session.turnId){
const accepted=nativeTurns(side).find(t=>t.clientUserMessageId===session.messageId);
if(!accepted?.turnId)throw Error('上次提交结果尚未确认,请稍后点击继续');
session.turnId=accepted.turnId;session.phase='waiting';await save();
}
if(session.requestId!==requestId||!session.turnId){
signal?.throwIfAborted();
Object.assign(session,{requestId,turnId:null,messageId:crypto.randomUUID(),phase:'submitting'});await save();
session.turnId=await native.Mr({scope,turnTrigger:'side_chat',manager,hostId,targetConversationId:session.sideId,cwd:parent.cwd,agentMode:'auto',permissionProfileId:null,shouldSendPermissionOverrides:false,activeCollaborationMode:mode,clientUserMessageId:session.messageId,
context:{prompt,collaborationMode:mode,workspaceRoots:[parent.cwd],imageAttachments:[],fileAttachments:[],addedFiles:[],commentAttachments:[],selectedTextAttachments:[],pastedTextAttachments:[],threadReferences:[]}});
session.phase='waiting';await save();
}
onProgress('GPT-5.6 Luna · 中 · 正在后台整理,可暂停后继续…');
// No fixed whole-job deadline: retain the turn identity when paused so that
// resume reads the existing response instead of launching duplicate work.
for(;;){
signal?.throwIfAborted();
const conversation=manager.getConversation(session.sideId);
if(!conversation)throw Error('后台整理会话已失效,已完成批次仍保留;点击继续可重新处理本批');
const turn=nativeTurns(conversation).find(t=>t.turnId===session.turnId);
if(turn&&turn.status!=='inProgress'){
if(turn.status!=='completed'||turn.error){session.requestId=null;session.turnId=null;session.phase='ready';await save();throw Error('本批整理中断,已完成批次已保存,可点击继续');}
if(session.phase!=='completed')session.batches=(session.batches||0)+1;
session.phase='completed';await save();
return turn.items.filter(i=>i.type==='agentMessage'&&(i.phase==null||i.phase==='final_answer')).map(i=>i.text??'').join('\n');
}
await new Promise(resolve=>setTimeout(resolve,1000));
}
}
// OpenAI-compatible Chat Completions. Never persist credentials in tree checkpoints.
function apiEndpoint(raw){
let url;try{url=new URL(String(raw).trim());}catch{throw Error('请输入完整的 HTTPS API 地址');}
if(url.protocol!=='https:'||url.username||url.password||url.search||url.hash)throw Error('API 地址须使用 HTTPS,且不含账号、密码、查询参数或片段');
const path=url.pathname.replace(/\/+$/,'');
url.pathname=path.endsWith('/chat/completions')?path:(path||'/v1')+'/chat/completions';
return url.href;View on GitHub (pinned to b1ed92e5e4)