BigPizzaV3/CodexPlusPlus · error

Codex setting-storage 接口不可用

Error message

Codex setting-storage 接口不可用 (${errors.join("; ")})

What it means

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.

Solutions

  1. 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).
  2. Retry probing after a delay to let lazy chunks load.
  3. Add new assetPrefix candidates covering the renamed module.
  4. Pin/downgrade Codex to a version compatible with the inject script.

Example fix

// before
const settingStorage = await codexSettingStorageModule();
// after
let settingStorage;
try { settingStorage = await codexSettingStorageModule(); }
catch (e) { console.warn("setting-storage probe failed:", e.message); await sleep(1000); settingStorage = await codexSettingStorageModule(); }
Defensive patterns

Strategy: fallback

Validate before calling

let ok = false; try { ok = !!(await codexSettingStorageModule()); } catch { ok = false; } if (!ok) { /* show "Codex 版本不兼容" banner */ }

Type guard

function isSettingStorage(mod) { return !!mod && typeof mod === "object"; }

Try / catch

try { const storage = await codexSettingStorageModule(); } catch (e) { console.warn(e.message); notifyUser("Codex 设置接口不可用,请更新注入脚本"); return null; }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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

Appendix: source

Thrown at assets/inject/renderer-inject.js:2647

    }
    return typeof getSetting === "function" && typeof setSetting === "function"
      ? { n: getSetting, s: setSetting, assetPrefix }
      : null;
  }

  async function codexSettingStorageModule() {
    const errors = [];
    for (const assetPrefix of ["setting-storage-", "app-initial-"]) {
      try {
        const module = await loadCodexAppModule(assetPrefix);
        const settingStorage = codexSettingStorageFromModule(module, assetPrefix);
        if (settingStorage) return settingStorage;
        errors.push(`${assetPrefix}: setting exports unavailable`);
      } catch (error) {
        errors.push(`${assetPrefix}: ${error?.message || String(error)}`);
      }
    }
    throw new Error(`Codex setting-storage 接口不可用 (${errors.join("; ")})`);
  }

  async function getCodexServiceTierSetting() {
    try {
      const read = (async () => {
        const settingStorage = await codexSettingStorageModule();
        return await settingStorage.n(codexDefaultServiceTierSetting);
      })();
      return await Promise.race([
        read,
        new Promise((_, reject) => setTimeout(() => reject(new Error("Codex 应用设置读取超时")), codexServiceTierReadTimeoutMs)),
      ]);
    } catch (error) {
      if (typeof codexStateCall === "function") {
        const fallbackRead = codexStateCall("get-setting", { params: { key: codexDefaultServiceTierSetting.key } });
        const result = await Promise.race([
          fallbackRead,
          new Promise((_, reject) => setTimeout(() => reject(error), codexServiceTierReadTimeoutMs)),

View on GitHub (pinned to b1ed92e5e4)