can1357/oh-my-pi · error · Error
git-subdir path "${source.path}" does not exist in cloned re
Error message
git-subdir path "${source.path}" does not exist in cloned repository What it means
Thrown by verifyDirExists (via resolveRelativeSource/resolveObjectSource) after a marketplace plugin source of type git-subdir has been cloned: the configured `source.path` subdirectory does not exist inside the cloned repository, or exists but is a file rather than a directory. The resolver validates the target immediately after cloning and cleans up the temp clone before failing, so a stale/partial clone is never left behind. It is a data/config validation error in the plugin source definition, not an infrastructure failure.
Source
Thrown at packages/coding-agent/src/extensibility/plugins/marketplace/source-resolver.ts:156
case "npm":
throw new Error("npm plugin sources are not yet supported. Use git-based sources instead.");
default:
throw new Error(`Unknown plugin source type: "${(source as { source: string }).source}"`);
}
}
// ── Helpers ─────────────────────────────────────────────────────────
async function verifyDirExists(dirPath: string, errorMessage: string): Promise<void> {
try {
const stat = await fs.stat(dirPath);
if (!stat.isDirectory()) {
throw new Error(errorMessage);
}
} catch (err) {
if (isEnoent(err)) {
throw new Error(errorMessage);
}
throw err;
}
}
View on GitHub (pinned to 9690622007)
Solutions
- Check the repository at the pinned branch/commit and correct `source.path` to the actual directory that exists (case-sensitive).
- Point `path` at a directory, not a file — the plugin manifest file should be inside the directory.
- If pinning a `sha`, update the pin to a commit where the subdirectory exists (e.g. the latest commit on the plugin's branch).
- If you control the plugin repo, restore/recreate the directory at the referenced path or publish a corrected marketplace catalog entry.
Example fix
// before
{ "source": "git", "repo": "acme/plugins", "path": "plugin/my-tool" }
// after (actual repo layout is plugins/my-tool)
{ "source": "git", "repo": "acme/plugins", "path": "plugins/my-tool" } Defensive patterns
Strategy: validation
Validate before calling
import * as fs from "node:fs/promises";
async function gitSubdirSourceLooksValid(repoDir: string, sourcePath: string) {
try {
return (await fs.stat(path.join(repoDir, sourcePath))).isDirectory();
} catch {
return false;
}
} Type guard
function isNonEmptyRelativeDir(p: string): boolean {
return typeof p === "string" && p.length > 0 && !path.isAbsolute(p) && !p.endsWith("/") && !p.includes("..");
} Try / catch
try {
const resolved = await resolveObjectSource(source);
} catch (err) {
if (err instanceof Error && err.message.includes('does not exist in cloned repository')) {
// surface source.path + repo so the user can fix the marketplace entry
throw new Error(`Plugin source path "${source.path}" not found in ${source.repo} at the pinned branch/commit`);
}
throw err;
} Prevention
- Pin sources to a branch/commit where you have verified the directory exists, and re-verify after upstream refactors.
- Keep source.path a directory, never a file path.
- Match path casing exactly to the repo layout (case-sensitive filesystems and git).
- After renaming directories in a plugin repo, bump the pinned sha/branch in every marketplace catalog that references it.
When it happens
Trigger: Resolving a plugin source `{ source: "git", path: "..." }` where (1) the `path` is misspelled or uses the wrong case relative to the actual repo layout, (2) the subdirectory was renamed or deleted in the branch/commit being cloned, (3) `path` points at a file (e.g. a plugin.json) instead of a directory, or (4) the `sha`/branch pins an older commit where the directory did not yet exist.
Common situations: A marketplace.json author publishes a plugin entry pointing at `plugins/foo` but the repo layout is `plugin/foo`; a plugin moves directories in a refactor and pinned `sha` values in user configs still reference the old layout; users hand-edit a marketplace catalog path with a trailing filename; typos like `./src/plugin` vs `src/plugin`.
Related errors
- Unable to read OMP_AUTH_BROKER_ACCOUNT_POOL_FILE at ${filePa
- Marketplace catalog not found at ${tried.map(p => `"${p}"`).
- Plugin "${pluginId}" is not installed in project scope
- Plugin "${pluginId}" is installed in both user and project s
- Plugin source directory does not exist: "${resolved}"
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/e62d4673b405b81c.
Report an issue: GitHub.