{"record":{"id":"51f1aab1d37a4ec1","repo":"rohitg00/agentmemory","slug":"agentmemory-could-not-locate-bundled-plugin-dire","errorCode":null,"errorMessage":"agentmemory: could not locate bundled plugin/ directory (searched up from ${here})","messagePattern":"agentmemory: could not locate bundled plugin/ directory \\(searched up from (.+?)\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/cli/connect/codex-hooks.ts","lineNumber":58,"sourceCode":" * module's own location looking for `plugin/scripts/` + `plugin/hooks/`,\n * both shipped via the npm `files` field. Works for both `dist/cli.mjs`\n * (bundled) and `src/cli/connect/codex-hooks.ts` (dev) layouts.\n */\nexport function findPluginRoot(startUrl: string = import.meta.url): string {\n  const here = dirname(fileURLToPath(startUrl));\n  let dir = here;\n  for (let i = 0; i < 12; i++) {\n    if (\n      existsSync(join(dir, \"plugin\", \"scripts\")) &&\n      existsSync(join(dir, \"plugin\", \"hooks\"))\n    ) {\n      return resolve(join(dir, \"plugin\"));\n    }\n    const parent = dirname(dir);\n    if (parent === dir) break;\n    dir = parent;\n  }\n  throw new Error(\n    `agentmemory: could not locate bundled plugin/ directory (searched up from ${here})`,\n  );\n}\n\n/**\n * Build the merged hooks.json content.\n *\n *   1. Strip any entry from `existing` whose first hook command points\n *      under `<pluginRoot>/scripts/`. This lets us re-install idempotently\n *      without leaving stale references.\n *   2. Append fresh entries from the bundled Codex manifest with\n *      `${CLAUDE_PLUGIN_ROOT}` rewritten to the absolute plugin path.\n *      Matcher values from the bundled manifest are preserved so PreToolUse\n *      event routing keeps working.\n */\nexport function buildMergedHooks(\n  existing: HookManifest | null,\n  pluginRoot: string,","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/rohitg00/agentmemory/blob/e04ba88819c365c9acf9d6661ea802143e728bd6/src/cli/connect/codex-hooks.ts#L40-L76","documentation":"agentmemory ships hook installer assets in a bundled plugin/ directory. findPluginRoot walks up from the running module's location looking for that directory, and throws if none is found. This indicates a broken/partial installation rather than a user input problem.","triggerScenarios":"Running `agentmemory connect` subcommands (codex, claude, droid, devin, antigravity hook installers) from an install where dist/ was copied without the plugin/ directory, or running from a globally installed package stripped of non-JS assets.","commonSituations":"npm global installs with --omit=optional or package 'files' whitelist excluding plugin/; copying dist/ into a container image without plugin/; running via a bundled binary or tsx from a temp dir.","solutions":["Reinstall agentmemory so plugin/ ships alongside dist/ (npm install -g agentmemory or fresh clone with npm install && npm run build).","Run the CLI from the repository/package root instead of a copied dist/ directory.","If packaging into a container/binary, explicitly include the plugin/ directory next to dist/.","Check the package 'files' field / publish pipeline if you maintain a fork."],"exampleFix":"// before (deploy script)\ncp -r dist/ /app/\n// after\ncp -r dist/ /app/\ncp -r plugin/ /app/","handlingStrategy":"validation","validationCode":"import { existsSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nlet dir = __dirname;\nwhile (dir !== dirname(dir)) {\n  if (existsSync(join(dir, 'plugin'))) break;\n  dir = dirname(dir);\n}\nif (!existsSync(join(dir, 'plugin'))) throw new Error('agentmemory installed without plugin/ assets');","typeGuard":"function hasPluginRoot(base: string): boolean {\n  try { return existsSync(join(base, 'plugin')) && statSync(join(base, 'plugin')).isDirectory(); }\n  catch { return false; }\n}","tryCatchPattern":"try {\n  await installCodexHooks();\n} catch (e) {\n  if (String(e.message).includes('could not locate bundled plugin/')) {\n    console.error('Reinstall agentmemory: npm i -g agentmemory');\n    process.exitCode = 1;\n  } else throw e;\n}","preventionTips":["Never copy dist/ without plugin/ when deploying.","Verify package integrity after global installs (ls node_modules/agentmemory/plugin).","Include plugin/ in Docker images and publish file lists.","Prefer running the CLI via its npm bin entry, not ad-hoc script copies."],"tags":["installation","hooks","filesystem","cli"],"backgroundTag":"bundled-asset-directory-missing","analyzedSha":"e04ba88819c365c9acf9d6661ea802143e728bd6","analyzedAt":"2026-08-30T01:07:40.754Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}