{"record":{"id":"0198768c4d783795","repo":"thedotmack/claude-mem","slug":"could-not-locate-a-codex-marketplace-root-with-ag","errorCode":null,"errorMessage":"Could not locate a Codex marketplace root with .agents/plugins/marketplace.json and plugin/.codex-plugin/plugin.json. Run npx claude-mem@latest install from the package or repo root.","messagePattern":"Could not locate a Codex marketplace root with \\.agents/plugins/marketplace\\.json and plugin/\\.codex-plugin/plugin\\.json\\. Run npx claude-mem@latest install from the package or repo root\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/services/integrations/CodexCliInstaller.ts","lineNumber":87,"sourceCode":"\nfunction resolvePluginMarketplaceRoot(preferredRoot?: string): string {\n  if (preferredRoot) {\n    return assertCodexMarketplaceRoot(preferredRoot);\n  }\n\n  const candidates = [\n    process.env.CLAUDE_PLUGIN_ROOT,\n    process.env.PLUGIN_ROOT,\n    process.cwd(),\n    path.dirname(fileURLToPath(import.meta.url)),\n  ].filter((value): value is string => Boolean(value));\n\n  for (const candidate of candidates) {\n    const resolved = findAncestorWithCodexMarketplace(candidate);\n    if (resolved && missingMarketplaceFiles(resolved).length === 0) return resolved;\n  }\n\n  throw new Error('Could not locate a Codex marketplace root with .agents/plugins/marketplace.json and plugin/.codex-plugin/plugin.json. Run npx claude-mem@latest install from the package or repo root.');\n}\n\nfunction lookupCodexOnWindows(): string | null {\n  let stdout: string;\n  try {\n    stdout = execFileSync('where.exe', ['codex'], {\n      encoding: 'utf-8',\n      stdio: ['ignore', 'pipe', 'ignore'],\n      windowsHide: true,\n    });\n  } catch (error) {\n    const err = error instanceof Error ? error : new Error(String(error));\n    logger.warn('WORKER', 'Failed to locate codex via where; falling back to codex.cmd', { command: 'where codex' }, err);\n    return null;\n  }\n\n  const candidates = stdout\n    .split(/\\r?\\n/)","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d768ba364302d12b76e69e4f021f0bb1d2d50ed6/src/services/integrations/CodexCliInstaller.ts#L69-L105","documentation":"resolvePluginMarketplaceRoot() tries four candidate locations in order (CLAUDE_PLUGIN_ROOT, PLUGIN_ROOT, process.cwd(), and the directory of the installer module) and walks each ancestor for a directory containing .agents/plugins/marketplace.json. If none yields a tree that also passes missingMarketplaceFiles, it throws telling the user to run install from the package/repo root.","triggerScenarios":"The Codex installer is invoked from a working directory that is not inside (and has no ancestor containing) a claude-mem plugin marketplace layout, AND neither CLAUDE_PLUGIN_ROOT nor PLUGIN_ROOT is set to a valid root.","commonSituations":"Running `npx claude-mem@latest install` from an unrelated project directory; running in a global npm cache location after npx fetch; CI ran install from /tmp or home without cloning; the plugin was never installed so no marketplace.json exists anywhere on disk.","solutions":["cd into the claude-mem repo/package root (where .agents/plugins/marketplace.json lives) and re-run the install.","Set CLAUDE_PLUGIN_ROOT (or PLUGIN_ROOT) to the absolute path of a tree containing .agents/plugins/marketplace.json before invoking the installer.","If installing from npm, run `npx claude-mem@latest install` and let it bootstrap the marketplace first; do not run the Codex step in isolation before that.","Confirm the marketplace.json actually exists at the expected path with a quick ls."],"exampleFix":"# before\npwd  # /tmp/some-unrelated-project\nnpx claude-mem@latest install --codex  # throws\n\n# after\nexport CLAUDE_PLUGIN_ROOT=\"$HOME/claude-mem\"\nnpx claude-mem@latest install --codex","handlingStrategy":"validation","validationCode":"import { existsSync } from 'fs';\nimport path from 'path';\n\nfunction resolveCodexRoot(): string | null {\n  const candidates = [process.env.CLAUDE_PLUGIN_ROOT, process.env.PLUGIN_ROOT, process.cwd()];\n  for (const c of candidates) {\n    if (!c) continue;\n    let cur = path.resolve(c);\n    while (true) {\n      if (existsSync(path.join(cur, '.agents', 'plugins', 'marketplace.json'))) return cur;\n      const parent = path.dirname(cur);\n      if (parent === cur) break;\n      cur = parent;\n    }\n  }\n  return null;\n}","typeGuard":"function isMarketplaceRootNotFound(e: unknown): boolean {\n  return e instanceof Error && /Could not locate a Codex marketplace root/i.test(e.message);\n}","tryCatchPattern":"try {\n  resolvePluginMarketplaceRoot();\n} catch (e) {\n  if (e instanceof Error && /Could not locate a Codex marketplace root/i.test(e.message)) {\n    console.error('cd into the claude-mem repo/package root, or set CLAUDE_PLUGIN_ROOT, then retry.');\n    process.exit(1);\n  }\n  throw e;\n}","preventionTips":["Run the installer from the repo/package root where marketplace.json lives.","Set CLAUDE_PLUGIN_ROOT explicitly in CI to avoid cwd ambiguity.","Do not invoke the Codex step in isolation before the core install."],"tags":["installer","codex","filesystem","env-vars","plugin-layout"],"backgroundTag":null,"analyzedSha":"d768ba364302d12b76e69e4f021f0bb1d2d50ed6","analyzedAt":"2026-08-12T23:52:55.241Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}