{"record":{"id":"97b7b735d87ddbeb","repo":"can1357/oh-my-pi","slug":"unsupported-internal-url-in-bash-command-url","errorCode":null,"errorMessage":"Unsupported internal URL in bash command: ${url}","messagePattern":"Unsupported internal URL in bash command: (.+?)","errorType":"validation","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/bash-skill-urls.ts","lineNumber":267,"sourceCode":"/** Shell-escape a path using single quotes. */\nfunction shellEscape(p: string): string {\n\treturn `'${p.replace(/'/g, \"'\\\\''\")}'`;\n}\n\nasync function resolveInternalUrlToPath(\n\trawUrl: string,\n\tskills: readonly Skill[],\n\tattachments: readonly ImageAttachmentEntry[],\n\tinternalRouter?: InternalUrlResolver,\n\tlocalOptions?: LocalProtocolOptions,\n\tensureLocalParentDirs?: boolean,\n\tcwd?: string,\n\tsessionFile?: string,\n): Promise<string> {\n\tconst url = normalizeLocalScheme(rawUrl);\n\tconst scheme = extractScheme(url);\n\tif (!scheme) {\n\t\tthrow new ToolError(`Unsupported internal URL in bash command: ${url}`);\n\t}\n\n\tif (scheme === \"skill\") {\n\t\treturn resolveSkillUrlToPath(url, skills);\n\t}\n\n\tif (scheme === \"attachment\") {\n\t\tconst attachment = attachments.find(entry => entry.uri === url);\n\t\tif (!attachment) {\n\t\t\tthrow new ToolError(`Unknown attachment URL in bash command: ${url}`);\n\t\t}\n\t\treturn path.resolve(attachment.sourcePath);\n\t}\n\n\tif (scheme === \"local\") {\n\t\tif (!localOptions) {\n\t\t\tthrow new ToolError(\n\t\t\t\t\"Cannot resolve local:// URL in bash command: local protocol options are unavailable for this session.\",","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/bash-skill-urls.ts#L249-L285","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nconst cmd = `cat skill:/pdf-guide/SKILL.md`;\n// after\nconst cmd = `cat skill://pdf-guide/SKILL.md`;","handlingStrategy":"validation","validationCode":"function isInternalUrl(u) { return /^[a-z][a-z0-9+.-]*:\\/\\//i.test(u); }\nif (!isInternalUrl(rawUrl)) throw new Error(`URL needs a scheme: ${rawUrl}`);","typeGuard":"const hasScheme = (u: string): u is `${string}://${string}` => /^[a-z][a-z0-9+.-]*:\\/\\//i.test(u);","tryCatchPattern":"try { await expandInternalUrls(cmd, ctx); } catch (e) { if (e instanceof ToolError && /Unsupported internal URL/.test(e.message)) fixScheme(e); else throw e; }","preventionTips":["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."],"tags":["bash","url-parsing","tool-error"],"backgroundTag":"unsupported-url-scheme","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}