can1357/oh-my-pi · error · ToolError

find cannot operate on a remote ssh:// path: ${rawPattern}.

Error message

find cannot operate on a remote ssh:// path: ${rawPattern}. ssh:// has no local file to glob; use `read ${rawPattern}` to list or inspect the remote path.

What it means

When a glob/find path entry is an internal URL the router can handle, ssh:// targets are explicitly rejected: a remote ssh path has no local filesystem to glob, so pattern matching is meaningless. The message directs you to the read tool, which can list/inspect remote paths.

Source

Thrown at packages/coding-agent/src/tools/glob.ts:214

			const rawPatternInputs = this.#customOps
				? effectivePaths
				: await expandDelimitedPathEntries(effectivePaths, this.session.cwd, { splitter: parseFindPattern });
			const rawPatterns = rawPatternInputs.map(input => normalizePathLikeInput(input).replace(/\\/g, "/"));
			const aliasResolvedPatterns = this.#rootPathAlias
				? rawPatterns.map(pattern => (/^\/+$/.test(pattern) ? "." : pattern))
				: rawPatterns;
			if (aliasResolvedPatterns.some(pattern => /^\/+$/.test(pattern))) {
				throw new ToolError("Searching from root directory '/' is not allowed");
			}
			const internalRouter = InternalUrlRouter.instance();
			const normalizedPatterns: string[] = [];
			for (const rawPattern of aliasResolvedPatterns) {
				if (!internalRouter.canHandle(rawPattern)) {
					normalizedPatterns.push(rawPattern);
					continue;
				}
				if (isSshUrl(rawPattern)) {
					throw new ToolError(
						`find cannot operate on a remote ssh:// path: ${rawPattern}. ssh:// has no local file to glob; use \`read ${rawPattern}\` to list or inspect the remote path.`,
					);
				}
				if (hasGlobPathChars(rawPattern)) {
					if (!/^memory:\/\//i.test(rawPattern)) {
						throw new ToolError(`Glob patterns are not supported for internal URLs: ${rawPattern}`);
					}
					const memoryGlob = splitMemoryGlobPattern(rawPattern);
					const resource = await internalRouter.resolve(memoryGlob.baseUrl, {
						cwd: this.session.cwd,
						settings: this.session.settings,
						signal,
						sessionFile: this.session.getSessionFile() ?? undefined,
						localProtocolOptions: this.session.localProtocolOptions,
						skills: this.session.skills,
						pathOnly: true,
					});
					if (!resource.sourcePath) {

View on GitHub (pinned to 9690622007)

Solutions

  1. Use the read tool for the ssh path: read 'ssh://host/path' instead of find
  2. Run find/glob on the remote host itself over ssh
  3. Glob only local paths or supported internal schemes (e.g. memory://)

Example fix

// before
await findTool({ path: "ssh://host/var/log" });
// after
await readTool({ path: "ssh://host/var/log" });
Defensive patterns

Strategy: validation

Validate before calling

import { isSshUrl } from "...";
if (typeof path === "string" && isSshUrl(path)) {
  // route to the read tool instead of find
  return readTool({ path });
}

Type guard

const isSshTarget = (p: string): boolean => /^ssh:\/\//i.test(p);

Try / catch

try {
  await globTool({ path: target });
} catch (err) {
  if (err instanceof ToolError && /ssh:\/\//.test(err.message)) {
    return readTool({ path: target });
  } else throw err;
}

Prevention

When it happens

Trigger: Passing path: 'ssh://host/path' (optionally with glob chars) to the glob/find tool; isSshUrl(rawPattern) is true for the routed entry.

Common situations: Copy-pasting an ssh remote URL from git config into a find call; assuming glob works over ssh remotes; scripted exploration of remote hosts with the wrong tool.

Related errors


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