can1357/oh-my-pi · error · ToolError

No such tool: . Mounted devices: . Active top-level tools…

Error message

No such tool: ${XD_URL_PREFIX}${name}. Mounted devices: ${[...state.mountedNames].join(", ")}. Active top-level tools are also dispatchable via ${XD_URL_PREFIX}<tool>.

What it means

resolveRequiredXdevTool looks up a device by name among the tools mounted in the xdev state. If no mounted device (and no active top-level tool alias) matches the requested name, it throws this ToolError listing all currently mounted device names and noting that top-level tools can also be dispatched via xd://<tool>.

Solutions

  1. Use one of the mounted device names listed in the error message.
  2. Fix the spelling of the device name (check for case/typo differences).
  3. Mount the needed device in the session before dispatching to it.
  4. Call the tool directly (top-level) if appropriate, or via `xd://<tool>` only for active top-level tools.

Example fix

// before
write({ path: "xd://browsers", content: "{...}" })
// after
write({ path: "xd://browser", content: "{...}" }) // name from mounted list
Defensive patterns

Strategy: validation

Validate before calling

if (!mountedDevices.includes(name)) throw new Error(`xd device not mounted: ${name}. Available: ${mountedDevices.join(", ")}`);

Type guard

function isMounted(name: string, state: { mountedNames: Iterable<string> }): boolean { return new Set(state.mountedNames).has(name); }

Try / catch

try { await dispatch(path, content); } catch (e) { if (String(e.message).startsWith("No such tool:")) { const mounted = e.message.match(/Mounted devices: ([^.]+)/)?.[1]?.split(", ") ?? []; /* pick correct or mount device */ } else throw e; }

Prevention

When it happens

Trigger: Calling Write/dispatch with `xd://<name>` where <name> is misspelled, not mounted in this session, or refers to a tool that exists but was excluded/unmounted.

Common situations: Typo in the device name; the session was started without mounting that device; a device was renamed across versions; assuming every top-level tool is available under xd:// when it was excluded.

Related errors


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

Appendix: source

Thrown at packages/coding-agent/src/tools/xdev.ts:399

	return sections.join("\n\n");
}

function shouldInlineXdevTool(
	state: XdevState,
	tool: Tool,
	mode: XdevDocsMode,
	inlineGlobs: readonly Bun.Glob[],
): boolean {
	return (
		mode !== "catalog" &&
		(mode === "inline" || state.builtInNames.has(tool.name) || inlineGlobs.some(glob => glob.match(tool.name)))
	);
}

function resolveRequiredXdevTool(state: XdevState, name: string): Tool {
	const inst = resolveXdevTool(state, name);
	if (!inst) {
		throw new ToolError(
			`No such tool: ${XD_URL_PREFIX}${name}. Mounted devices: ${[...state.mountedNames].join(", ")}. Active top-level tools are also dispatchable via ${XD_URL_PREFIX}<tool>.`,
		);
	}
	return inst;
}

/** Execute an enabled canonical tool through `write xd://<tool>`. */
export async function dispatchXdevTool(
	state: XdevState,
	name: string,
	content: string,
	toolCallId: string,
	signal?: AbortSignal,
	onUpdate?: AgentToolUpdateCallback,
	context?: AgentToolContext,
): Promise<{ result: AgentToolResult<unknown>; xdev: XdevDispatch }> {
	let xdev: XdevDispatch = { tool: name, mode: "execute" };
	try {

View on GitHub (pinned to 9690622007)