jackwener/OpenCLI · error
Invalid plugin source: "${source}" Supported formats: gith
Error message
Invalid plugin source: "${source}"
Supported formats:
github:user/repo
github:user/repo/subplugin
https://github.com/user/repo
https://<host>/<path>/repo.git
ssh://git@<host>/<path>/repo.git
git@<host>:user/repo.git
What it means
installPlugin first parses the source string with parseSource, which recognizes github: shorthand, GitHub HTTPS URLs, ssh://, SCP-style git@, generic HTTPS git URLs, file:// and absolute local paths. If nothing matches, a plain Error listing all supported formats is thrown so the caller can correct the input.
Source
Thrown at src/plugin.ts:697
writeLock?.(commitHash);
});
}
/**
* Install a plugin from a source.
* Supports:
* "github:user/repo" — single plugin or full monorepo
* "github:user/repo/subplugin" — specific sub-plugin from a monorepo
* "https://github.com/user/repo"
* "file:///absolute/path" — local plugin directory (symlinked)
* "/absolute/path" — local plugin directory (symlinked)
*
* Returns the installed plugin name(s).
*/
export function installPlugin(source: string): string | string[] {
const parsed = parseSource(source);
if (!parsed) {
throw new Error(
`Invalid plugin source: "${source}"\n` +
`Supported formats:\n` +
` github:user/repo\n` +
` github:user/repo/subplugin\n` +
` https://github.com/user/repo\n` +
` https://<host>/<path>/repo.git\n` +
` ssh://git@<host>/<path>/repo.git\n` +
` git@<host>:user/repo.git\n` +
` file:///absolute/path\n` +
` /absolute/path`
);
}
const { name: repoName, subPlugin } = parsed;
if (parsed.type === 'local') {
return installLocalPlugin(parsed.localPath!, repoName);
}View on GitHub (pinned to 49907e53dc)
Solutions
- Use a supported format, e.g. installPlugin('github:user/repo') or an absolute local path.
- For local development, pass an absolute path ('/abs/path/to/plugin') or file:///absolute/path — relative paths are rejected.
- Add a .git suffix or use https://github.com/user/repo for GitHub repos.
- For other git hosts use ssh://git@<host>/<path>/repo.git or git@<host>:user/repo.git.
- Trim whitespace and remove trailing slashes/query strings from the source string.
Example fix
// before
installPlugin('my-plugin'); // bare name
installPlugin('./plugins/my-plugin'); // relative path
// after
installPlugin('github:user/my-plugin');
installPlugin('/abs/path/plugins/my-plugin'); Defensive patterns
Strategy: validation
Validate before calling
const SOURCE_RE = /^(github:[\w.-]+\/[\w.-]+(\/[\w.-]+)?|https?:\/\/github\.com\/[\w.-]+\/[\w.-]+?(\.git)?|ssh:\/\/[^/]+\/.+|git@[^:]+:.+|https?:\/\/[^/]+\/.+|file:\/\/.+|\/.+)$/;
if (!SOURCE_RE.test(source)) throw new Error(`Unsupported plugin source: ${source}`); Try / catch
try {
installPlugin(source);
} catch (err) {
if (err.message.startsWith('Invalid plugin source')) {
// normalize the source string (add scheme/absolute path) and retry
} else throw err;
} Prevention
- Always pass one of the documented formats — never a bare plugin name.
- Use absolute paths (or file:// URLs) for local plugins; expand ~ yourself.
- Trim whitespace and strip trailing slashes from user-supplied sources.
- Prefer github:user/repo shorthand for GitHub repos.
When it happens
Trigger: installPlugin('my-plugin') (bare name), installPlugin('git://host/repo'), installPlugin('github:user') (missing repo segment), relative local paths like './my-plugin', URLs with extra path/query segments, or whitespace/typos in the source string.
Common situations: Passing a plugin NAME instead of a source; using a git:// protocol URL (unsupported); relative directory path instead of absolute; trailing slash or extra URL components; scp-style without .git and non-matching host prefix.
Related errors
- messageId "${raw}" is not a UUID or a "#channel:shortId" for
- Unknown 12306 station telecode "${trimmed}"
- Unknown 12306 station "${trimmed}"
- date must be YYYY-MM-DD, got "${value}"
- date "${value}" is not a real calendar date
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/68a3941ec39958c2.
Report an issue: GitHub.