jackwener/OpenCLI · error · PluginError
Local plugin path does not exist: ${localPath}
Error message
Local plugin path does not exist: ${localPath} What it means
installLocalPlugin symlinks a local directory into the plugins dir for plugin development. It throws a PluginError when the given path does not exist on disk (an adjacent check throws for non-directories). opencli throws this early so a clearly invalid path never gets symlinked or recorded in the lock file.
Source
Thrown at src/plugin.ts:772
upsertLockEntry(lock, pluginName, {
source: { kind: 'git', url: cloneUrl },
commitHash,
});
writeLockFile(lock);
}
});
return pluginName;
}
/**
* Install a local plugin by creating a symlink.
* Used for plugin development: the source directory is symlinked into
* the plugins dir so changes are reflected immediately.
*/
function installLocalPlugin(localPath: string, name: string): string {
if (!fs.existsSync(localPath)) {
throw new PluginError(`Local plugin path does not exist: ${localPath}`);
}
const stat = fs.statSync(localPath);
if (!stat.isDirectory()) {
throw new PluginError(`Local plugin path is not a directory: ${localPath}`);
}
const manifest = readPluginManifest(localPath);
if (manifest?.opencli && !checkCompatibility(manifest.opencli)) {
throw new PluginError(
`Plugin requires opencli ${manifest.opencli}, but current version is incompatible.`,
'Upgrade opencli to a compatible version.',
);
}
const pluginName = manifest?.name ?? name;
const targetDir = path.join(PLUGINS_DIR, pluginName);View on GitHub (pinned to 49907e53dc)
Solutions
- Verify the path exists: `ls <localPath>`; fix typos.
- Pass an absolute path (relative paths are resolved against the process cwd, which may differ from your shell).
- Rebuild/restore the plugin directory if it was deleted, or clone it again.
- Ensure the path points to a directory containing the plugin, not a file or archive.
- Use file:///absolute/path form if passing a file URL.
Example fix
// before
installPlugin('~/dev/my-plugin'); // ~ not expanded, doesn't exist
// after
installPlugin('/home/me/dev/my-plugin'); Defensive patterns
Strategy: validation
Validate before calling
import * as fs from 'node:fs';
import * as path from 'node:path';
const localPath = path.resolve(expandHome(inputPath));
if (!fs.existsSync(localPath)) throw new Error(`Path not found: ${localPath}`);
if (!fs.statSync(localPath).isDirectory()) throw new Error(`Not a directory: ${localPath}`); Try / catch
try {
installPlugin(localPath);
} catch (err) {
if (err instanceof PluginError && err.message.startsWith('Local plugin path does not exist')) {
// correct the path (resolve to absolute, expand ~) and retry
} else throw err;
} Prevention
- Always pass absolute paths for local plugins; expand ~ and resolve relative paths yourself.
- Confirm the directory exists with fs.existsSync before installing in scripts.
- Point at the plugin directory, not a file or zip archive.
- Re-verify dev-plugin paths after moving projects or switching machines/containers.
When it happens
Trigger: installPlugin('/abs/path/to/plugin') or installPlugin('file:///abs/path/to/plugin') where the path doesn't exist: typo in path, directory deleted/renamed, path valid on another machine, or passing a relative path resolved against the wrong cwd.
Common situations: Plugin development folder moved or removed; wrong absolute path after switching machines/containers; passing a file instead of a directory; shell tab-completion used a stale path; Windows vs POSIX path style confusion.
Related errors
- Verify command returned no metric for baseline
- File not found: ${path}
- File must be a readable text file: ${path}
- File could not be read: ${path}
- state.vscdb not found: ${db}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/aa27403d89661eda.
Report an issue: GitHub.