{"record":{"id":"5178b375c1c5a1c8","repo":"BigPizzaV3/CodexPlusPlus","slug":"codex-native-sidechat","errorCode":null,"errorMessage":"当前 Codex 版本的对话读取接口不兼容","messagePattern":"当前 Codex 版本的对话读取接口不兼容","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"tools/conversation-canvas/src/native-sidechat.js","lineNumber":5,"sourceCode":"// Runtime bindings are versioned separately. History reading does not require\n// the private side-conversation submission API to be available.\nasync function nativeContext(threadId){\n  const native=await loadNativeRuntime();\n  if(typeof native.ESt!=='function'||typeof native.kr!=='function')throw Error('当前 Codex 版本的对话读取接口不兼容');\n  native.kr();\n  const scopes=[],callbacks=[],seeds=[],navigation=[];\n  const visited=new Set(),domVisited=new Set();\n  // ProseMirror owns the inner editable DOM. React's expando is on a wrapper,\n  // not necessarily on the contenteditable itself. Start from native surfaces\n  // too, so history reading remains available while the composer is hidden.\n  for(const element of document.querySelectorAll('[contenteditable],textarea,main,[data-testid=\"app-shell-header-context-menu-surface\"]')){\n    for(let dom=element;dom&&!domVisited.has(dom);dom=dom.parentElement){\n      domVisited.add(dom);\n      for(const key of Object.keys(dom)){\n        if(key.startsWith('__reactFiber$'))seeds.push(dom[key]);\n        if(key.startsWith('__reactContainer$')){\n          const root=dom[key];seeds.push(root?.stateNode?.current??root);\n        }\n      }\n    }\n  }\n  const inspect=fiber=>{","sourceCodeStart":1,"sourceCodeEnd":23,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6/tools/conversation-canvas/src/native-sidechat.js#L1-L23","documentation":"nativeContext loads the versioned native runtime and requires two history-reading bindings, ESt and kr. If either is not a function, the current Codex version's conversation-reading interface is incompatible and this error is thrown. History reading is kept separate from the private side-chat submission API so it can work even when that API is absent.","triggerScenarios":"nativeContext(threadId) called (directly or via readNativeHistory callers: navigation, manager, native/scope/manager/parent paths) on a Codex build whose runtime lacks ESt or kr.","commonSituations":"Codex app update renamed/removed the history-read bindings; canvas script's binding map out of date; running an unsupported Codex channel (beta/nightly).","solutions":["Update the conversation canvas script to match the installed Codex version","Confirm your Codex version is in the script's supported list","Downgrade Codex to a supported release if no script update exists yet","Extend the runtime binding map (ESt/kr) for the new Codex build"],"exampleFix":"// before\nif(typeof native.ESt!=='function'||typeof native.kr!=='function')throw Error('当前 Codex 版本的对话读取接口不兼容');\n// after\nif(typeof native.ESt!=='function'||typeof native.kr!=='function')throw Error(`当前 Codex 版本的对话读取接口不兼容（缺少 ESt=${typeof native.ESt}, kr=${typeof native.kr}），请更新对话脉络脚本`);","handlingStrategy":"fallback","validationCode":"async function canReadHistory(){try{const n=await loadNativeRuntime();return typeof n.ESt==='function'&&typeof n.kr==='function';}catch{return false;}}","typeGuard":"const historyBindingsOk=(n)=>typeof n?.ESt==='function'&&typeof n?.kr==='function';","tryCatchPattern":"try{await nativeContext(id);}catch(e){if(/不兼容/.test(e.message)){showUpdateBanner();useExportFallback();}else throw e;}","preventionTips":["Verify history bindings at script startup and fall back to bridge export if absent","Track Codex release notes for internal API renames","Keep the binding map in one versioned module"],"tags":["runtime-binding","history-read","version-incompatibility"],"backgroundTag":"incompatible-source-type","analyzedSha":"b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6","analyzedAt":"2026-09-19T23:35:21.129Z","contentChangedAt":"2026-09-19T23:35:21.129Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}