jackwener/OpenCLI · error
External CLI '${name}' not found in registry.
Error message
External CLI '${name}' not found in registry. What it means
executeExternalCli looks up the requested tool name in the registry loaded by loadExternalClis (or the preloaded list). If no config with that exact name exists, it throws because there is no binary or install strategy to fall back on.
Source
Thrown at src/external.ts:186
}
log.info(`'${cli.name}' is not installed. Auto-installing...`);
log.verbose(`$ ${cmd}`);
try {
runInstallCommand(cmd);
log.success(`Installed '${cli.name}' successfully.`);
return true;
} catch (err) {
log.error(`Failed to install '${cli.name}': ${getErrorMessage(err)}`);
return false;
}
}
export function executeExternalCli(name: string, args: string[], preloaded?: ExternalCliConfig[]): void {
const configs = preloaded ?? loadExternalClis();
const cli = configs.find((c) => c.name === name);
if (!cli) {
throw new Error(`External CLI '${name}' not found in registry.`);
}
// 1. Check if installed
if (!isBinaryInstalled(cli.binary)) {
// 2. Try to auto install
const success = installExternalCli(cli);
if (!success) {
process.exitCode = EXIT_CODES.SERVICE_UNAVAIL;
return;
}
}
// 3. Passthrough execution with stdio inherited
const result = spawnPassthrough(cli.binary, args);
if (result.error) {
log.error(`Failed to execute '${cli.binary}': ${result.error.message}`);
process.exitCode = EXIT_CODES.GENERIC_ERROR;
return;View on GitHub (pinned to 49907e53dc)
Solutions
- Check the exact registered name (list the registry / loadExternalClis output) and correct the name, matching case exactly.
- Add the tool to the registry config file that loadExternalClis reads, with name, binary, and install command fields.
- If a preloaded list is passed, verify it actually contains the CLI you are invoking.
Example fix
// before
executeExternalCli("git-leaks", ["detect"]);
// after (if registry entry is named 'gitleaks')
executeExternalCli("gitleaks", ["detect"]); Defensive patterns
Strategy: validation
Validate before calling
const configs = loadExternalClis();
if (!configs.some((c) => c.name === name)) {
throw new Error(`'${name}' not registered. Known: ${configs.map((c) => c.name).join(", ")}`);
}
executeExternalCli(name, args); Type guard
function isRegistered(name: string, configs: ExternalCliConfig[]): boolean {
return configs.some((c) => c.name === name);
} Try / catch
try {
executeExternalCli(name, args);
} catch (e) {
if (/not found in registry/.test(e.message)) {
console.error(`Unknown CLI '${name}'. Add it to the registry or fix the name.`);
}
} Prevention
- Keep a single source of truth for CLI names and import/derive names from it.
- Use exact-match constants instead of hand-typed strings when invoking.
- Validate config files against a schema listing required registry entries.
When it happens
Trigger: Calling executeExternalCli(name, args) or passthroughExternal with a name that does not exactly match any c.name in loadExternalClis() output, e.g. a typo or a tool not present in the registry config file.
Common situations: Typo in CLI name ('gitleaks' vs 'git-leaks'); registry file missing the tool entry; casing mismatch since lookup is exact; config file at a different path than the one the library reads.
Related errors
- Maven Central has no published versions for ${coordLabel}.
- npm registry returned 404 for ${url}.
- NOT_FOUND
- NOT_FOUND
- bilibili creator-stats ${bvid}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/d250dcc75df0206c.
Report an issue: GitHub.