{"record":{"id":"1a4f1f9577239f16","repo":"BigPizzaV3/CodexPlusPlus","slug":"codex-setting-storage-errors-join","errorCode":null,"errorMessage":"Codex setting-storage 接口不可用 (${errors.join(\"; \")})","messagePattern":"Codex setting-storage 接口不可用 \\((.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"assets/inject/renderer-inject.js","lineNumber":2647,"sourceCode":"    }\n    return typeof getSetting === \"function\" && typeof setSetting === \"function\"\n      ? { n: getSetting, s: setSetting, assetPrefix }\n      : null;\n  }\n\n  async function codexSettingStorageModule() {\n    const errors = [];\n    for (const assetPrefix of [\"setting-storage-\", \"app-initial-\"]) {\n      try {\n        const module = await loadCodexAppModule(assetPrefix);\n        const settingStorage = codexSettingStorageFromModule(module, assetPrefix);\n        if (settingStorage) return settingStorage;\n        errors.push(`${assetPrefix}: setting exports unavailable`);\n      } catch (error) {\n        errors.push(`${assetPrefix}: ${error?.message || String(error)}`);\n      }\n    }\n    throw new Error(`Codex setting-storage 接口不可用 (${errors.join(\"; \")})`);\n  }\n\n  async function getCodexServiceTierSetting() {\n    try {\n      const read = (async () => {\n        const settingStorage = await codexSettingStorageModule();\n        return await settingStorage.n(codexDefaultServiceTierSetting);\n      })();\n      return await Promise.race([\n        read,\n        new Promise((_, reject) => setTimeout(() => reject(new Error(\"Codex 应用设置读取超时\")), codexServiceTierReadTimeoutMs)),\n      ]);\n    } catch (error) {\n      if (typeof codexStateCall === \"function\") {\n        const fallbackRead = codexStateCall(\"get-setting\", { params: { key: codexDefaultServiceTierSetting.key } });\n        const result = await Promise.race([\n          fallbackRead,\n          new Promise((_, reject) => setTimeout(() => reject(error), codexServiceTierReadTimeoutMs)),","sourceCodeStart":2629,"sourceCodeEnd":2665,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6/assets/inject/renderer-inject.js#L2629-L2665","documentation":"codexSettingStorageModule() probes one or more injected asset prefixes (webpack chunk require) trying to obtain Codex's setting-storage exports. Every probe throws (module renamed, chunk not loaded, bundler internals changed), and after exhausting all prefixes it aggregates the collected messages into this error. It indicates the inject script can no longer reach Codex's internal settings API surface.","triggerScenarios":"Calling getCodexServiceTierSetting() (or any setting read) when all `assetPrefix` probes fail: Codex app updated and the setting-storage module id/path changed, webpack chunk graph changed, or the inject script loads before the target chunk exists.","commonSituations":"Codex desktop/renderer upgraded with refactored internals; inject script version lagging behind the app; CSP or bundling changes blocking the chunk require; race where probing runs before lazy chunks load.","solutions":["Update the inject script to the module ids/paths used by the installed Codex version (check the error's per-prefix messages for which probes failed).","Retry probing after a delay to let lazy chunks load.","Add new assetPrefix candidates covering the renamed module.","Pin/downgrade Codex to a version compatible with the inject script."],"exampleFix":"// before\nconst settingStorage = await codexSettingStorageModule();\n// after\nlet settingStorage;\ntry { settingStorage = await codexSettingStorageModule(); }\ncatch (e) { console.warn(\"setting-storage probe failed:\", e.message); await sleep(1000); settingStorage = await codexSettingStorageModule(); }","handlingStrategy":"fallback","validationCode":"let ok = false; try { ok = !!(await codexSettingStorageModule()); } catch { ok = false; } if (!ok) { /* show \"Codex 版本不兼容\" banner */ }","typeGuard":"function isSettingStorage(mod) { return !!mod && typeof mod === \"object\"; }","tryCatchPattern":"try { const storage = await codexSettingStorageModule(); } catch (e) { console.warn(e.message); notifyUser(\"Codex 设置接口不可用，请更新注入脚本\"); return null; }","preventionTips":["Ship inject script updates alongside each Codex release you support.","Log each per-prefix probe error to speed up diagnosing renamed modules.","Delay first probe until the app's chunks are loaded (e.g. after app-ready event)."],"tags":["injection","codex","module","version-mismatch"],"backgroundTag":"module-init-failed","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"}