BigPizzaV3/CodexPlusPlus · error · Error
result?.message||'Codex++ 会话读取失败'
Error message
result?.message||'Codex++ 会话读取失败'
What it means
Same guard as the userscript sync loop, but in tools/conversation-canvas/src/canvas-panel.js (the packaged panel). When readCanvasSource returns a non-ok result or nothing at all, it throws Error(result?.message || 'Codex++ 会话读取失败') so the sync rejects with the bridge's error message.
Solutions
- Match panel and host/bridge versions
- Read the underlying result.message and fix the root cause (missing file, permissions)
- Retry the sync or re-open the panel
- Show the failure in status and retain the last good canvas data
Defensive patterns
Strategy: try-catch
Validate before calling
if (!result || result.status !== 'ok') throw new Error(result?.message || 'Codex++ 会话读取失败');
Try / catch
catch(e){ status(`同步失败:${e.message}`); /* retain last rendered graph */ } Prevention
- Keep panel and host versions in sync
- Log the underlying bridge message for diagnosis
- Retry sync after host restart
When it happens
Trigger: Any sync in the panel where the session-read bridge reports {status:'error'} or resolves null/undefined — host absent, rollout file unreadable, request dropped.
Common situations: Panel running against an outdated Codex++ host; rollout jsonl missing for the requested thread; permissions or path errors inside the host reading the session file.
Related errors
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19).
Data as JSON: /api/errors/68f85b07142ce174.
Report an issue: GitHub.
Appendix: source
Thrown at tools/conversation-canvas/src/canvas-panel.js:285
const messages=await readNativeHistory((method,params)=>manager.sendRequest(method,params,{priority:'background',timeoutMs:15000}),id,historyCache,progress,signal);
const signature=[];for(const message of messages){signal.throwIfAborted();signature.push(message.id+':'+await messageDigest(message));}
return {status:'ok',kind:'canvas-messages',session_id:id,messages,content:signature.join('|')};
}
async function sync(force=false){
const id=currentId();
if(!id){historyAbort?.abort();requestSequence++;active='';pending=null;data=null;revision='';taskCanvas.context('');$('pending-tray').replaceChildren();$('transcript').replaceChildren();$('details').hidden=true;status('请打开具体任务。');return;}
if(id!==active){
historyAbort?.abort();taskCanvas.context(id);pendingOffset=0;pendingOpen=false;sourceState={page:0};collapsedByThread.set(active,collapsedNodes);collapsedNodes=collapsedByThread.get(id)||new Set();active=id;organizationStatus(organizing===id?'GPT-5.6 Luna · 中 · 正在后台整理…':'');requestSequence++;pending=null;data=null;revision='';selected=null;lastRead=0;
$('pending-tray').replaceChildren();$('transcript').replaceChildren();$('details').hidden=true;$('subtitle').textContent='';$('title').textContent='当前对话';tab('map');
}
if(pending===id||(!force&&Date.now()-lastRead<5000))return;
const seq=++requestSequence;pending=id;lastRead=Date.now();if(!data)status('正在读取当前对话…');
const abort=new AbortController();historyAbort=abort;
try{
await hydrateAnnotations(id);
const result=await readCanvasSource(id,abort.signal,text=>{if(!disposed&&seq===requestSequence)status(text);});
if(disposed||seq!==requestSequence||id!==currentId())return;
if(result?.status!=='ok')throw new Error(result?.message||'Codex++ 会话读取失败');
if(!data||result.content!==revision){
data=result.kind==='canvas-messages'?{threadId:id,title:storedAnnotations(id).title||'当前对话',messages:result.messages,...buildGraph(result.messages,storedAnnotations(id))}:graphFromExport(result,id,storedAnnotations(id));revision=result.content;render();
diagnostic('native_data',{nodeCount:data.nodes.length,messageCount:data.messages.length});
}
status(`已同步${nativeReadTasks.has(id)?'(原生分页)':''} · ${data.nodes.filter(n=>n.summaryKind!=='原文摘录').length} 个任务节点`);
}catch(e){
if(!disposed&&seq===requestSequence){status(`读取失败:${e.message}`);diagnostic('native_error',{message:e.message});}
}finally{if(seq===requestSequence)pending=null;}
}
function closePanel(){pane.classList.remove('open');toggle.setAttribute('aria-expanded','false');}
$('organize').onclick=organize;
$('pause-organize').onclick=()=>organizationAbort.abort();
retry.onclick=()=>sync(true);
toggle.onclick=()=>{const open=pane.classList.toggle('open');toggle.setAttribute('aria-expanded',String(open));updatePanelBounds();if(open){sync(true);taskCanvas.refresh();}};
$('close').onclick=()=>{closePanel();toggle.focus();};
$('pending-tray').addEventListener('toggle',e=>{if(e.target.classList?.contains('pending-messages'))pendingOpen=e.target.open;},true);
$('pending-tray').onclick=e=>{
const page=e.target.closest('[data-pending-page]');if(page){pendingOffset=Number(page.dataset.pendingPage);pendingOpen=true;renderTree();return;}View on GitHub (pinned to b1ed92e5e4)