can1357/oh-my-pi · error · Error

Unknown tool: ${tool}

Error message

Unknown tool: ${tool}

What it means

downloadTool() looks up the tool's metadata in the TOOLS registry before doing any network work. If the requested name is not a registered ToolName, it throws immediately with the unknown name — a guard against programming errors rather than an environmental failure.

Source

Thrown at packages/coding-agent/src/utils/tools-manager.ts:220

		});
		if (!response.ok) {
			throw new Error(`Failed to download: ${response.status}`);
		} else if (!response.body) {
			throw new Error("No response body");
		}
		await writeResponseBody(dest, response.body, downloadSignal);
	} catch (err) {
		if (isAbortLikeError(err)) {
			throw new Error(`Download timed out: ${url}`);
		}
		throw err;
	}
}

// Download and install a tool
async function downloadTool(tool: ToolName, signal?: AbortSignal): Promise<string> {
	const config = TOOLS[tool];
	if (!config) throw new Error(`Unknown tool: ${tool}`);

	const plat = os.platform();
	const architecture = os.arch();

	// Get latest version
	const version = await getLatestVersion(config.repo, signal);

	// Get asset name for this platform
	const assetName = config.getAssetName(version, plat, architecture);
	if (!assetName) {
		throw new Error(`Unsupported platform: ${plat}/${architecture}`);
	}

	// Create tools directory
	await fs.promises.mkdir(TOOLS_DIR, { recursive: true });

	const downloadUrl = `https://github.com/${config.repo}/releases/download/${config.tagPrefix}${version}/${assetName}`;
	const binaryExt = plat === "win32" ? ".exe" : "";

View on GitHub (pinned to 9690622007)

Solutions

  1. Fix the tool name to one of the supported ToolName values defined in TOOLS.
  2. If using dynamic/config-driven names, validate against the known tool list before calling.
  3. Upgrade the package if the tool was added in a newer version of the manager.
  4. Install the missing tool manually and reference it via its system path instead.

Example fix

// before: await toolsManager.path("ripgrep") // throws Unknown tool: ripgrep | // after: await toolsManager.path("rg") // correct registered name
Defensive patterns

Strategy: validation

Validate before calling

// validate the tool name against the registry before calling | const SUPPORTED = new Set(["rg", "fd", "sg", "ast-grep"]); if (!SUPPORTED.has(toolName)) throw new Error(`Unsupported tool: ${toolName}`);

Type guard

function isKnownTool(name: string): name is ToolName { return (["rg", "fd", "sg", "ast-grep"] as string[]).includes(name); }

Try / catch

try { const p = await toolsManager.path(toolName); } catch (err) { if (err.message.startsWith("Unknown tool:")) { /* reject the config entry / prompt user for a valid tool */ } else throw err; }

Prevention

When it happens

Trigger: Calling downloadTool/path/download with a tool name not present in the TOOLS map, e.g. a typo ("ripgrep" instead of "rg") or a tool added upstream but not in this version of the manager.

Common situations: Typos in tool identifiers, code written against a newer/older tool list, dynamic tool names derived from user input or config files containing an unsupported entry.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/d664878a51da6d1b. Report an issue: GitHub.