{"record":{"id":"11f98a8ca13d13c0","repo":"EveryInc/compound-engineering-plugin","slug":"cannot-switch-to-local-mode-while-the-local-collec","errorCode":null,"errorMessage":"Cannot switch to local mode while the local collection is ${previous.kind}","messagePattern":"Cannot switch to local mode while the local collection is (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/dev/codex-dev.ts","lineNumber":560,"sourceCode":"    plugins.some((plugin) => plugin.pluginId === OFFICIAL_PLUGIN_ID) ||\n    (await isOfficialPluginConfigured(context))\n  ) {\n    await runCodex(context, runner, [\"plugin\", \"remove\", OFFICIAL_PLUGIN_ID, \"--json\"])\n  }\n  await removePlugins(\n    context,\n    runner,\n    plugins.filter((plugin) => plugin.pluginId !== OFFICIAL_PLUGIN_ID),\n  )\n}\n\nexport async function switchToLocal(\n  context: CodexDevContext,\n  runner: CommandRunner = new BunCommandRunner(),\n): Promise<CodexDevStatus> {\n  const previous = await inspectLocalCollection(context)\n  if (previous.kind !== \"absent\" && previous.kind !== \"valid\") {\n    throw new Error(`Cannot switch to local mode while the local collection is ${previous.kind}`)\n  }\n  const activatedTarget = await fs.realpath(context.skillsRoot)\n  await activateLocalCollection(context)\n  try {\n    const plugins = await listCompoundEngineeringPlugins(context, runner)\n    await removeLocalPluginConflicts(context, runner, plugins)\n    const status = await inspectCodexDevStatus(context, runner)\n    if (status.mode !== \"local\") {\n      throw new Error(`Could not verify local Codex development mode (reported ${status.mode})`)\n    }\n    return status\n  } catch (error) {\n    await restoreLocalCollection(context, previous, activatedTarget)\n    throw error\n  }\n}\n\nasync function listMarketplaces(context: CodexDevContext, runner: CommandRunner): Promise<Marketplace[]> {","sourceCodeStart":542,"sourceCodeEnd":578,"githubUrl":"https://github.com/EveryInc/compound-engineering-plugin/blob/c9c10f8c75412c7232cb2bd663e5fd1cea98d84e/src/dev/codex-dev.ts#L542-L578","documentation":"switchToLocal() only proceeds when the collection path is 'absent' or already a 'valid' managed link. Any other state (collision, unrelated, broken) is rejected up front with this error, so the caller fixes the path state before activation can be attempted.","triggerScenarios":"Calling switchToLocal() (via runCodexDevCommand or status-driven flows) when inspectLocalCollection returns kind='collision' (real file/dir), 'unrelated' (symlink outside a CE checkout), or 'broken' (dangling symlink).","commonSituations":"A real skills directory or another plugin's symlink already occupies the collection path; the previous local checkout was deleted leaving a dangling link; a hand-made symlink to the wrong repository.","solutions":["Run `bun run codex:dev -- status` to see the reported state","For 'collision': back up and remove the non-symlink directory/file at collectionPath yourself, then retry","For 'broken': delete the dangling symlink (`rm <collectionPath>`) or restore the missing checkout, then retry","For 'unrelated': re-point or remove the foreign symlink once confirmed it is not needed, then retry"],"exampleFix":"# before (dangling link from a deleted checkout)\n$ bun run codex:dev -- local\n// Error: Cannot switch to local mode while the local collection is broken\n\n# after\n$ rm /path/to/CODEX_HOME/skills/compound-engineering-local\n$ bun run codex:dev -- local   # now state is 'absent' and activation proceeds","handlingStrategy":"validation","validationCode":"const state = await inspectLocalCollection(context);\nif (state.kind !== \"absent\" && state.kind !== \"valid\") {\n  // remediate first: rm dangling/foreign links, move aside real dirs\n  console.warn(`collection is ${state.kind}; fix before switching to local`);\n} else {\n  await switchToLocal(context);\n}","typeGuard":"function canSwitchToLocal(s: { kind: string }): boolean {\n  return s.kind === \"absent\" || s.kind === \"valid\";\n}","tryCatchPattern":"try {\n  await switchToLocal(context);\n} catch (e) {\n  if (String(e).includes(\"Cannot switch to local mode\")) {\n    const kind = String(e).match(/collection is (\\w+)/)?.[1];\n    console.error(`remediate state '${kind}' (see status), then retry`);\n  } else throw e;\n}","preventionTips":["Check `bun run codex:dev -- status` before every mode switch","Keep the checkout path stable so links never dangle","Remove foreign or manual entries at the collection path before installing"],"tags":["symlink","state-guard","filesystem","codex-dev"],"backgroundTag":"broken-symlink","analyzedSha":"c9c10f8c75412c7232cb2bd663e5fd1cea98d84e","analyzedAt":"2026-08-31T15:18:07.959Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}