EveryInc/compound-engineering-plugin · error · Error

Plugin directory not found

Error message

Plugin directory not found: ${pluginPath}

What it means

The `plugin-path` command resolves (cloning if needed) the plugin repository, then uses `resolvePluginRoot` to find the plugin directory inside it and verifies it with `dirExists`. This error means the clone succeeded but no directory for the requested plugin name exists at the expected location, so there is no path to print.

Solutions

  1. Check the plugin directory name in the source repo (see `.claude-plugin/marketplace.json`).
  2. If using --branch, switch to a branch that contains the plugin (e.g. main).
  3. Correct the plugin name spelling and re-run.
  4. If COMPOUND_PLUGIN_GITHUB_SOURCE is set, verify it points at the right repository.

Example fix

// before
plugin-path compund-engineering
// after
plugin-path compound-engineering
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the plugin name matches a directory in the source repo before calling
const res = await fetch(`https://api.github.com/repos/<owner>/<repo>/contents/plugins`)
const dirs = (await res.json()).map((e: any) => e.name)
if (!dirs.includes(pluginName)) throw new Error(`No plugin dir named ${pluginName}`)

Try / catch

try {
  const p = await pluginPath(pluginName)
} catch (e) {
  if (e instanceof Error && e.message.startsWith("Plugin directory not found")) {
    console.error(`Wrong plugin name or branch; check the repo layout`) 
  } else throw e
}

Prevention

When it happens

Trigger: Running `plugin-path <plugin-name>` where the source repo does not contain a directory matching the plugin name — misspelled name, plugin renamed upstream, or the cloned ref (branch) predates the plugin's addition.

Common situations: Requesting a plugin from an older branch that doesn't have it yet; typo in the plugin name; source override (COMPOUND_PLUGIN_GITHUB_SOURCE) pointing at a repo without the plugin.

Related errors


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

Appendix: source

Thrown at src/commands/plugin-path.ts:49

      .replace(/\//g, "~")
      .replace(/[^a-zA-Z0-9._~-]/g, (ch) => `%${ch.charCodeAt(0).toString(16).padStart(2, "0")}`)
    const dirName = `${pluginName}-${sanitized}`
    const cacheRoot = path.join(os.homedir(), ".cache", "compound-engineering", "branches")
    await fs.mkdir(cacheRoot, { recursive: true })
    const targetDir = path.join(cacheRoot, dirName)
    const source = resolveGitHubSource()

    if (await dirExists(targetDir)) {
      console.error(`Updating existing checkout at ${targetDir}`)
      await fetchAndCheckout(targetDir, branch)
    } else {
      console.error(`Cloning ${branch} to ${targetDir}`)
      await cloneBranch(source, targetDir, branch)
    }

    const pluginPath = await resolvePluginRoot(targetDir, pluginName)
    if (!(await dirExists(pluginPath))) {
      throw new Error(`Plugin directory not found: ${pluginPath}`)
    }

    // Plugin path goes to stdout (for scripting); usage hint goes to stderr
    console.error(`\nReady. Use with:\n  claude --plugin-dir ${pluginPath}\n`)
    console.log(pluginPath)
  },
})

async function dirExists(p: string): Promise<boolean> {
  try {
    const stat = await fs.stat(p)
    return stat.isDirectory()
  } catch {
    return false
  }
}

async function resolvePluginRoot(repoDir: string, pluginName: string): Promise<string> {

View on GitHub (pinned to c9c10f8c75)