can1357/oh-my-pi · error · ToolError
Unsupported internal URL in bash command: ${url}
Error message
Unsupported internal URL in bash command: ${url} What it means
resolveInternalUrlToPath maps internal URLs used in bash commands (skill://, attachment://, local://, plus router-backed schemes) to filesystem paths. Before dispatching on the scheme it calls extractScheme; if the token has no recognizable scheme, it throws this ToolError. This guards the bash tool from blindly passing an opaque token to scheme-specific resolvers that would fail confusingly.
Source
Thrown at packages/coding-agent/src/tools/bash-skill-urls.ts:267
/** Shell-escape a path using single quotes. */
function shellEscape(p: string): string {
return `'${p.replace(/'/g, "'\\''")}'`;
}
async function resolveInternalUrlToPath(
rawUrl: string,
skills: readonly Skill[],
attachments: readonly ImageAttachmentEntry[],
internalRouter?: InternalUrlResolver,
localOptions?: LocalProtocolOptions,
ensureLocalParentDirs?: boolean,
cwd?: string,
sessionFile?: string,
): Promise<string> {
const url = normalizeLocalScheme(rawUrl);
const scheme = extractScheme(url);
if (!scheme) {
throw new ToolError(`Unsupported internal URL in bash command: ${url}`);
}
if (scheme === "skill") {
return resolveSkillUrlToPath(url, skills);
}
if (scheme === "attachment") {
const attachment = attachments.find(entry => entry.uri === url);
if (!attachment) {
throw new ToolError(`Unknown attachment URL in bash command: ${url}`);
}
return path.resolve(attachment.sourcePath);
}
if (scheme === "local") {
if (!localOptions) {
throw new ToolError(
"Cannot resolve local:// URL in bash command: local protocol options are unavailable for this session.",View on GitHub (pinned to 9690622007)
Solutions
- Check the URL string in the failing bash command and add the missing '://' scheme separator (e.g. 'skill://name/path' not 'skill:/name/path').
- Use a scheme the tool understands: skill, attachment, local, or one registered with the session's internal URL router.
- If generating URLs programmatically, run them through the same normalizeLocalScheme/extractScheme validation before embedding in the command.
- Replace the internal URL with a direct filesystem path if no internal scheme applies.
Example fix
// before const cmd = `cat skill:/pdf-guide/SKILL.md`; // after const cmd = `cat skill://pdf-guide/SKILL.md`;
Defensive patterns
Strategy: validation
Validate before calling
function isInternalUrl(u) { return /^[a-z][a-z0-9+.-]*:\/\//i.test(u); }
if (!isInternalUrl(rawUrl)) throw new Error(`URL needs a scheme: ${rawUrl}`); Type guard
const hasScheme = (u: string): u is `${string}://${string}` => /^[a-z][a-z0-9+.-]*:\/\//i.test(u); Try / catch
try { await expandInternalUrls(cmd, ctx); } catch (e) { if (e instanceof ToolError && /Unsupported internal URL/.test(e.message)) fixScheme(e); else throw e; } Prevention
- Always include the full scheme:// prefix when referencing internal resources in bash.
- Validate generated URLs with a scheme regex before embedding them in commands.
- Copy URIs from tool output rather than retyping them.
- Prefer direct filesystem paths when no internal scheme applies.
When it happens
Trigger: expandInternalUrls found a token that looks like an internal URL reference in a bash command, but after normalizeLocalScheme the string has no scheme (no '<scheme>://' prefix), e.g. a bare 'skill/foo.md' without the 'skill://' prefix, a typo'd scheme separator like 'skill:/path', or an empty/malformed URI passed where an internal URL is expected.
Common situations: Hand-written bash commands referencing internal resources with missing or malformed scheme syntax; templates or prompt text that dropped the '://' when interpolating URIs; copying a path from docs and omitting the scheme prefix.
Related errors
- Discord webhook credential is not a valid URL
- Discord webhook credential does not contain a webhook ID and
- Discord attachment URL is invalid
- ${destination} returned an invalid image URL
- the configured endpoint is not a valid URL
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/97b7b735d87ddbeb.
Report an issue: GitHub.