BigPizzaV3/CodexPlusPlus · warning · Error
当前 Codex 的 HTTP 服务尚未就绪,请稍后重试
Error message
当前 Codex 的 HTTP 服务尚未就绪,请稍后重试
What it means
nativeApiRequest() requires the runtime's HTTP client: native.cGt.getInstance() must expose fetch and native.jR.httpFetch must be truthy. When either is absent, the HTTP service exists in principle but is not initialized/ready, so this transient error is thrown.
Solutions
- Retry shortly — the message says the service isn't ready yet ('请稍后重试')
- Ensure the app/host is fully loaded before triggering organize
- Update the userscript if the bindings have changed names
- Switch to the external channel as a workaround
Example fix
// before await nativeApiRequest(url, opts); // fired at app startup // after await delay(2000); await nativeApiRequest(url, opts); // retry after host warm-up
Defensive patterns
Strategy: retry
Validate before calling
const ready = n => typeof n?.lGt==='function' && typeof n?.cGt?.getInstance?.()?.fetch==='function' && !!n?.jR?.httpFetch; // poll until ready before requesting
Type guard
function httpServiceReady(n){return typeof n?.cGt?.getInstance?.()?.fetch==='function' && !!n?.jR?.httpFetch;} Try / catch
try{ await nativeApiRequest(url,opts) }catch(e){ if(e.message.includes('尚未就绪')){ await delay(1500); return nativeApiRequest(url,opts); } throw e; } Prevention
- Wait for full app startup before organizing
- Add a readiness probe/poll loop before first request
- Retry transiently with backoff
When it happens
Trigger: native runtime loaded and lGt called, but client?.fetch is not a function or native.jR.httpFetch is falsy — the host HTTP service hasn't finished initializing.
Common situations: Request issued immediately after app startup before the host service is ready; race during app initialization; Codex build exposing partially initialized bindings.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- bridge context is not initialized
- 当前 Codex 版本的 API 适配器不兼容,请更新对话脉络脚本
- 当前 Codex 版本未提供兼容的 HTTP 服务
- 当前 Codex 的 HTTP 服务尚未就绪,请稍后重试
- 当前任务的原生接口尚未就绪,请等待任务加载后点击刷新
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19).
Data as JSON: /api/errors/656fd08b3e4206f4.
Report an issue: GitHub.
Appendix: source
Thrown at tools/conversation-canvas/public/canvas.user.js:770
const delay=retryDelayMs*2**attempt;
progress(`${error.message};${Math.ceil(delay/1000)} 秒后自动重试 ${attempt+1}/${maxRetries}(可能重复计费)…`);
// Pausing during backoff must not submit another request.
let timer;try{await waitForApi(new Promise(resolve=>{timer=setTimeout(resolve,delay);}),signal);}finally{clearTimeout(timer);}
}finally{clearInterval(heartbeat);}
}
}
return {run,dispose};
}
// HTTP uses the app host, with versioned runtime bindings, not renderer fetch/CSP.
async function nativeApiRequest(url,options){
const localError=message=>Object.assign(Error(message),{canvasApiLocal:true});
let native;
try{native=await loadNativeRuntime();}catch{throw localError('当前 Codex 版本的 API 适配器不兼容,请更新对话脉络脚本');}
if(typeof native.lGt!=='function')throw localError('当前 Codex 版本未提供兼容的 HTTP 服务');
native.lGt();
const client=native.cGt?.getInstance?.();
if(typeof client?.fetch!=='function'||!native.jR?.httpFetch)throw localError('当前 Codex 的 HTTP 服务尚未就绪,请稍后重试');
const {onProgress,...fetchOptions}=options;
const response=await client.fetch(url,fetchOptions);
return readApiResponse(response,options.signal,onProgress);
}
const canvasNodeSize={width:268,height:132,gapX:88,gapY:34};
// Iterative preorder/reverse traversal keeps deep histories off the JS call stack.
function layoutTaskCanvas(nodes,currentNodeId,collapsed=new Set()){
const view=visibleTreeRows(nodes,currentNodeId,collapsed),children=new Map(),positions=new Map();
const {width,height,gapX,gapY}=canvasNodeSize;
for(const row of view.rows){const list=children.get(row.node.parent)||[];list.push(row.node.id);children.set(row.node.parent,list);}
let leaf=0;
for(const row of view.rows)if(!children.has(row.node.id))positions.set(row.node.id,leaf++*(height+gapY));
for(let i=view.rows.length-1;i>=0;i--){const row=view.rows[i],list=children.get(row.node.id);if(list)positions.set(row.node.id,(positions.get(list[0])+positions.get(list.at(-1)))/2);}
const cards=view.rows.map(row=>({...row,x:row.depth*(width+gapX),y:positions.get(row.node.id),width,height}));
const byId=new Map(cards.map(card=>[card.node.id,card]));View on GitHub (pinned to b1ed92e5e4)