can1357/oh-my-pi · error · ToolError

Failed to resolve ${scheme}:// URL in bash command: ${url} $

Error message

Failed to resolve ${scheme}:// URL in bash command: ${url}
${message}

What it means

The internal router accepted the URL but its resolve() call threw. resolveInternalUrlToPath catches the underlying error and rewraps it as a ToolError, prefixing the original message with the scheme and URL so the failure is traceable back to the specific bash-command URL.

Source

Thrown at packages/coding-agent/src/tools/bash-skill-urls.ts:307

		if (ensureLocalParentDirs) {
			await fs.mkdir(path.dirname(resolvedLocalPath), { recursive: true });
		}
		return resolvedLocalPath;
	}

	if (!internalRouter?.canHandle(url)) {
		throw new ToolError(
			`Cannot resolve ${scheme}:// URL in bash command: ${url}\n` +
				"Internal URL router is unavailable for this protocol in the current session.",
		);
	}

	let resource: InternalResource;
	try {
		resource = await internalRouter.resolve(url, { cwd, pathOnly: true, sessionFile });
	} catch (error) {
		const message = error instanceof Error ? error.message : String(error);
		throw new ToolError(`Failed to resolve ${scheme}:// URL in bash command: ${url}\n${message}`);
	}

	if (!resource.sourcePath) {
		throw new ToolError(`${scheme}:// URL resolved without a filesystem path and cannot be used in bash: ${url}`);
	}

	return path.resolve(resource.sourcePath);
}

/**
 * Expand all skill:// URIs in a bash command string.
 * Returns the command with URIs replaced by shell-escaped absolute paths.
 * Throws ToolError if any URI cannot be resolved.
 */
export function expandSkillUrls(command: string, skills: readonly Skill[]): string {
	if (skills.length === 0 || !command.includes("skill://")) {
		return command;
	}

View on GitHub (pinned to 9690622007)

Solutions

  1. Read the embedded underlying message after the URL in the error text — it states the real cause from the handler.
  2. Verify the referenced resource exists and its identifier is correct for the handler.
  3. Run the command with the expected cwd/sessionFile so handler resolution has its required context.
  4. Test the same URL through the router outside bash to isolate handler vs command issues.
Defensive patterns

Strategy: try-catch

Try / catch

try { await expandInternalUrls(cmd, ctx); } catch (e) { if (e instanceof ToolError && e.message.startsWith('Failed to resolve')) { const cause = e.message.split('\n')[2]; /* diagnose cause, then retry or rethrow */ } else throw e; }

Prevention

When it happens

Trigger: internalRouter.canHandle(url) was true, but router.resolve(url, { cwd, pathOnly: true, sessionFile }) raised — e.g. the referenced resource doesn't exist, the session file is missing, permissions deny access, or the handler itself failed validation.

Common situations: Referencing a resource id that no longer exists (deleted skill/file in a handler scheme); handler backends that depend on cwd or sessionFile being set but invoked without them; network/auth failures inside a remote-backed scheme handler.

Related errors


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