BigPizzaV3/CodexPlusPlus · error · Error

当前 Codex 版本的 API 适配器不兼容,请更新对话脉络脚本

Error message

当前 Codex 版本的 API 适配器不兼容,请更新对话脉络脚本

What it means

nativeApiRequest() relies on the Codex host's versioned native runtime bindings. If loadNativeRuntime() fails (binding missing/renamed in this Codex build), the script cannot do HTTP through the app host and throws this error telling the user to update the userscript.

Solutions

  1. Update the 对话脉络 (conversation canvas) userscript to the latest version
  2. Check the installed Codex version against the script's supported versions
  3. Fall back to the 'external' API channel, which uses direct HTTP
  4. Reinstall/repair the Codex app if the runtime module is genuinely missing

Example fix

// before
channel: 'native' // old userscript + new Codex
// after
channel: 'external' // bypass native runtime, or update userscript
Defensive patterns

Strategy: fallback

Validate before calling

let native; try{ native=await loadNativeRuntime(); }catch{ useExternalChannel(); }

Type guard

function nativeRuntimeAvailable(){return typeof window!=='undefined' && !!window.__codexNativeRuntimeLoader__;}

Try / catch

try{ await nativeApiRequest(url,opts) }catch(e){ if(e.message.includes('适配器不兼容')){ fallbackToExternal(); } else throw e; }

Prevention

When it happens

Trigger: Channel 'native' request where loadNativeRuntime() rejects — the expected runtime module/binding is absent or incompatible with the running Codex version.

Common situations: Codex app updated and internal runtime APIs changed; userscript older than the installed Codex version; running in an environment without the app-host runtime (plain browser).

Understand the failure class

Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.

Related errors


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

Appendix: source

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

      catch(error){
        clearInterval(heartbeat);
        signal?.throwIfAborted();
        if(!error.retryable||attempt>=maxRetries)throw error;
        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;

View on GitHub (pinned to b1ed92e5e4)