can1357/oh-my-pi · error · ToolError
${scheme}:// URL resolved without a filesystem path and cann
Error message
${scheme}:// URL resolved without a filesystem path and cannot be used in bash: ${url} What it means
The router resolved the URL successfully but returned an InternalResource without a sourcePath. Since bash commands can only operate on real filesystem paths, the tool refuses to substitute anything and throws this ToolError, naming the scheme and URL.
Source
Thrown at packages/coding-agent/src/tools/bash-skill-urls.ts:311
}
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;
}
return command.replace(SKILL_URL_PATTERN, token => {
const url = unquoteToken(token);
const resolvedPath = resolveSkillUrlToPath(url, skills);View on GitHub (pinned to 9690622007)
Solutions
- Materialize the resource to a real file first (e.g. write it via a tool that supports it) and reference that path in bash.
- Fix or update the plugin handler so it returns a sourcePath for pathOnly requests.
- Use a scheme with filesystem backing (skill://, local://, attachment://) in bash commands.
- If you control the handler, ensure InternalResource.sourcePath is always populated for bash-capable resources.
Defensive patterns
Strategy: fallback
Try / catch
try { await expandInternalUrls(cmd, ctx); } catch (e) { if (e instanceof ToolError && /resolved without a filesystem path/.test(e.message)) materializeResourceToFile(e); else throw e; } Prevention
- Use bash only for schemes with filesystem backing; handle virtual resources with tools that read them directly.
- If you write handlers, always populate InternalResource.sourcePath for pathOnly resolution.
- Materialize in-memory resources to temp files before shell commands need them.
When it happens
Trigger: A handler returns an in-memory/virtual resource (e.g. generated content, a stream, a URI with no filesystem backing) for a URL used inside a bash command; a custom plugin handler implements resolve() but doesn't populate resource.sourcePath when pathOnly: true is requested.
Common situations: Plugin schemes backed by databases, remote fetches, or virtual documents being referenced in bash commands; a handler bug where sourcePath is only set on some code paths.
Related errors
- Cannot resolve ${scheme}:// URL in bash command: ${url} Inte
- Failed to resolve ${scheme}:// URL in bash command: ${url} $
- %%bash requires a POSIX bash, but none was found. Install Gi
- Command exited with code ${result.exitCode}
- Command aborted
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/62e860640a56e021.
Report an issue: GitHub.