EveryInc/compound-engineering-plugin · error · Error

Could not verify remote Codex mode (reported ${status.mode})

Error message

Could not verify remote Codex mode (reported ${status.mode})

What it means

The final self-check of `switchToRemote()`: after removing the local collection and re-adding the official plugin, `inspectCodexDevStatus` must report `"remote"`. Any other reported mode (`"mixed"`, `"drifted"`, etc.) means leftover local state still conflicts with the marketplace install, so the error is thrown.

Source

Thrown at src/dev/codex-dev.ts:639

  const plugins = await listCompoundEngineeringPlugins(context, runner)
  await removePlugins(
    context,
    runner,
    collection.kind === "valid"
      ? plugins
      : plugins.filter((entry) => entry.pluginId !== OFFICIAL_PLUGIN_ID),
  )
  await runCodex(context, runner, ["plugin", "add", OFFICIAL_PLUGIN_ID, "--json"])

  const installed = await listCompoundEngineeringPlugins(context, runner)
  if (installed.length !== 1 || !isOfficialMarketplacePlugin(installed[0]!)) {
    throw new Error("Could not verify the official marketplace-backed Compound Engineering plugin")
  }

  await removeLocalCollection(context)
  const status = await inspectCodexDevStatus(context, runner)
  if (status.mode !== "remote") {
    throw new Error(`Could not verify remote Codex mode (reported ${status.mode})`)
  }
  return status
}

export async function removeCodexDevInstallation(
  context: CodexDevContext,
  runner: CommandRunner = new BunCommandRunner(),
): Promise<CodexDevStatus> {
  const plugins = await listCompoundEngineeringPlugins(context, runner)
  await removeLocalPluginConflicts(context, runner, plugins)
  await removeLocalCollection(context)
  const status = await inspectCodexDevStatus(context, runner)
  if (status.mode !== "absent") {
    throw new Error(`Could not verify removal (reported ${status.mode})`)
  }
  return status
}

View on GitHub (pinned to c9c10f8c75)

Solutions

  1. Run `codex:dev -- status` to see mode and collection details
  2. Run `bun run codex:dev -- remove` and then retry `codex:dev -- remote`
  3. Check for and manually remove leftover `compound-engineering-local` skill symlinks under `$CODEX_HOME/skills`
  4. Start a new Codex session after switching

Example fix

// before: retry with dirty state
await switchToRemote(context, runner) // throws
// after
await removeCodexDevInstallation(context, runner)
await switchToRemote(context, runner)
Defensive patterns

Strategy: try-catch

Validate before calling

const collection = await inspectLocalCollection(context)
if (collection.kind !== "absent") await removeLocalCollection(context)

Type guard

function isRemoteStatus(status: CodexDevStatus): boolean { return status.mode === "remote" }

Try / catch

try {
  await switchToRemote(context, runner)
} catch (error) {
  if (String(error).includes("remote Codex mode")) {
    const status = await inspectCodexDevStatus(context)
    console.error("Post-switch mode:", status.mode, "— clean up and retry with codex:dev -- remove")
  } else throw error
}

Prevention

When it happens

Trigger: Calling `switchToRemote(context, runner)` when, after `removeLocalCollection` and `plugin add`, `inspectCodexDevStatus` still sees local artifacts or mismatched plugin state — e.g. the local collection removal failed silently or a stale `codex:dev` marker keeps the status in `mixed`/`drifted`.

Common situations: Interrupted earlier `codex:dev` runs leaving half-cleaned state; worktree-specific leftovers under `$CODEX_HOME`; plugins list contains entries from multiple checkouts.

Related errors


AI-assisted analysis of EveryInc/compound-engineering-plugin@c9c10f8c75 (2026-08-31). Data as JSON: /api/errors/129067566fad7df0. Report an issue: GitHub.