{"record":{"id":"3b68493e96053e5c","repo":"EveryInc/compound-engineering-plugin","slug":"local-plugin-path-not-found-directpath","errorCode":null,"errorMessage":"Local plugin path not found: ${directPath}","messagePattern":"Local plugin path not found: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/commands/cleanup.ts","lineNumber":661,"sourceCode":"}\n\nfunction resolveCleanupTargets(targetArg: string): CleanupTarget[] {\n  if (targetArg === \"all\") return [...cleanupTargets]\n  const targets = targetArg.split(\",\").map((entry) => entry.trim()).filter(Boolean)\n  for (const target of targets) {\n    if (!cleanupTargets.includes(target as CleanupTarget)) {\n      throw new Error(`Unknown cleanup target: ${target}. Use one of: ${cleanupTargets.join(\", \")}, all`)\n    }\n  }\n  return targets as CleanupTarget[]\n}\n\nasync function resolveCleanupPluginPath(input: string): Promise<string> {\n  if (input.startsWith(\".\") || input.startsWith(\"/\") || input.startsWith(\"~\")) {\n    const expanded = expandHome(input)\n    const directPath = path.resolve(expanded)\n    if (await pathExists(directPath)) return directPath\n    throw new Error(`Local plugin path not found: ${directPath}`)\n  }\n\n  const repoRoot = fileURLToPath(new URL(\"../..\", import.meta.url))\n  const rootManifestPath = path.join(repoRoot, \".claude-plugin\", \"plugin.json\")\n  if (await pathExists(rootManifestPath)) {\n    try {\n      const raw = await fs.readFile(rootManifestPath, \"utf8\")\n      const manifest = JSON.parse(raw) as { name?: string }\n      if (manifest.name === input) return repoRoot\n    } catch {\n      // Fall through to legacy multi-plugin layout.\n    }\n  }\n\n  const legacyPluginPath = path.join(repoRoot, \"plugins\", input)\n  const legacyManifestPath = path.join(legacyPluginPath, \".claude-plugin\", \"plugin.json\")\n  if (await pathExists(legacyManifestPath)) return legacyPluginPath\n","sourceCodeStart":643,"sourceCodeEnd":679,"githubUrl":"https://github.com/EveryInc/compound-engineering-plugin/blob/c9c10f8c75412c7232cb2bd663e5fd1cea98d84e/src/commands/cleanup.ts#L643-L679","documentation":"When the `--plugin` argument to `cleanup` looks like a filesystem path (starts with `.`, `/`, or `~`), `resolveCleanupPluginPath` expands `~` and resolves it, then checks existence. If the resolved directory does not exist on disk it throws this error with the fully resolved path, so the message shows exactly where it looked.","triggerScenarios":"Passing `--plugin ./nonexistent`, `--plugin ~/plugins/compound-engineering` when the directory was moved/deleted, or an absolute path with a typo. The path must also be a loadable plugin dir for later steps, but this specific error fires purely on non-existence of the resolved path.","commonSituations":"Relative path run from the wrong working directory (\"./\" resolves against CWD); a checkout deleted or relocated after cloning; `~` expansion pointing at another user's home in CI; Windows-style paths that don't resolve on the host OS.","solutions":["Check the resolved path printed in the error exists: ls <path>/.claude-plugin/plugin.json.","Run the command from the directory you based the relative path on, or switch to an absolute path.","If you meant the bundled plugin rather than a local checkout, omit the leading ./, / or ~ and pass the plugin name (e.g. --plugin compound-engineering)."],"exampleFix":"// before (run from repo root, but plugin lives elsewhere)\nbun run src/index.ts cleanup --plugin ./plugins/compound-engineering\n// Error: Local plugin path not found: /repo/plugins/compound-engineering\n\n// after\nbun run src/index.ts cleanup --plugin /absolute/path/to/compound-engineering","handlingStrategy":"validation","validationCode":"import { existsSync } from \"node:fs\"\nimport { resolve } from \"node:path\"\nconst direct = resolve(input.replace(/^~(?=\\/|$)/, process.env.HOME ?? \"\"))\nif (input.startsWith(\".\") || input.startsWith(\"/\") || input.startsWith(\"~\")) {\n  if (!existsSync(direct)) throw new Error(`Plugin path does not exist: ${direct}`)\n  if (!existsSync(direct + \"/.claude-plugin/plugin.json\")) throw new Error(`Missing plugin manifest at ${direct}`)\n}","typeGuard":"function isExistingPluginPath(p: string): p is string & { __pluginDir: true } {\n  return existsSync(p) && existsSync(path.join(p, \".claude-plugin\", \"plugin.json\"))\n}","tryCatchPattern":"try {\n  await cleanup({ plugin: pluginArg })\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith(\"Local plugin path not found:\")) {\n    console.error(`Path ${e.message.split(\": \")[1]} does not exist. Check CWD and spelling.`)\n  } else throw e\n}","preventionTips":["Prefer absolute paths for --plugin in scripts; relative paths resolve against the current working directory.","Verify the directory contains .claude-plugin/plugin.json before passing it.","Remember `~` inside quotes may not be expanded by the shell — the CLI expands it, but test in your environment."],"tags":["cli","filesystem","path-resolution"],"backgroundTag":"path-not-found","analyzedSha":"c9c10f8c75412c7232cb2bd663e5fd1cea98d84e","analyzedAt":"2026-08-31T15:18:07.959Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}