BigPizzaV3/CodexPlusPlus · error · Error

本批整理中断,已完成批次已保存,可点击继续

Error message

本批整理中断,已完成批次已保存,可点击继续

What it means

The polling loop found the tracked turn with a terminal status that is not a clean completion: status !== 'completed' or turn.error is set. The code resets requestId/turnId and phase to 'ready' (so clicking continue resubmits this batch) and throws. Completed batches already counted remain saved.

Solutions

  1. Click 继续 to retry the failed batch; state was reset to 'ready' so it will resubmit.
  2. Inspect the side conversation's turn error in the Codex UI for the underlying cause.
  3. If the model keeps erroring, switch organizer model/effort or use the external API mode with a different provider.
  4. Retry after a wait if the cause was rate limiting or a transient backend error.

Example fix

// before
if(turn.status!=='completed'||turn.error){ ...throw Error('本批整理中断,已完成批次已保存,可点击继续'); }
// after
if(turn.status!=='completed'||turn.error){
  if(++batchRetries<3) return retryBatch(); // auto-retry with backoff
  ...throw Error('本批整理中断,已完成批次已保存,可点击继续');
}
Defensive patterns

Strategy: retry

Validate before calling

const turn = nativeTurns(conversation).find(t => t.turnId === session.turnId); const healthy = turn && turn.status === 'completed' && !turn.error;

Type guard

const turnSucceeded = (t) => t?.status === 'completed' && !t?.error;

Try / catch

try { await nativeSideChat(...); } catch (e) { if (e.message.includes('整理中断')) { await backoff(); retryBatch(); } else throw e; }

Prevention

When it happens

Trigger: Turn finished as 'failed'/'aborted', or completed with a non-empty turn.error — model error, permission denial inside the side task, or the turn was cancelled.

Common situations: Model refused/errored on the batch prompt; the side turn was aborted when the user paused or the app suspended; rate limiting or backend error on the model (gpt-5.6-luna) endpoint.

Related errors


AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19). Data as JSON: /api/errors/7f0e65829f238b0a. Report an issue: GitHub.

Appendix: source

Thrown at tools/conversation-canvas/public/canvas.user.js:611

    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;
}

function apiConfig(input){

View on GitHub (pinned to b1ed92e5e4)