{"record":{"id":"ba52e95235488318","repo":"can1357/oh-my-pi","slug":"failed-to-resolve-scheme-url-in-bash-command","errorCode":null,"errorMessage":"Failed to resolve ${scheme}:// URL in bash command: ${url}\n${message}","messagePattern":"Failed to resolve (.+?):// URL in bash command: (.+?)\n(.+?)","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/bash-skill-urls.ts","lineNumber":307,"sourceCode":"\t\tif (ensureLocalParentDirs) {\n\t\t\tawait fs.mkdir(path.dirname(resolvedLocalPath), { recursive: true });\n\t\t}\n\t\treturn resolvedLocalPath;\n\t}\n\n\tif (!internalRouter?.canHandle(url)) {\n\t\tthrow new ToolError(\n\t\t\t`Cannot resolve ${scheme}:// URL in bash command: ${url}\\n` +\n\t\t\t\t\"Internal URL router is unavailable for this protocol in the current session.\",\n\t\t);\n\t}\n\n\tlet resource: InternalResource;\n\ttry {\n\t\tresource = await internalRouter.resolve(url, { cwd, pathOnly: true, sessionFile });\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tthrow new ToolError(`Failed to resolve ${scheme}:// URL in bash command: ${url}\\n${message}`);\n\t}\n\n\tif (!resource.sourcePath) {\n\t\tthrow new ToolError(`${scheme}:// URL resolved without a filesystem path and cannot be used in bash: ${url}`);\n\t}\n\n\treturn path.resolve(resource.sourcePath);\n}\n\n/**\n * Expand all skill:// URIs in a bash command string.\n * Returns the command with URIs replaced by shell-escaped absolute paths.\n * Throws ToolError if any URI cannot be resolved.\n */\nexport function expandSkillUrls(command: string, skills: readonly Skill[]): string {\n\tif (skills.length === 0 || !command.includes(\"skill://\")) {\n\t\treturn command;\n\t}","sourceCodeStart":289,"sourceCodeEnd":325,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/bash-skill-urls.ts#L289-L325","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read the embedded underlying message after the URL in the error text — it states the real cause from the handler.","Verify the referenced resource exists and its identifier is correct for the handler.","Run the command with the expected cwd/sessionFile so handler resolution has its required context.","Test the same URL through the router outside bash to isolate handler vs command issues."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"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; }","preventionTips":["Parse the underlying message embedded after the URL in the error to find the real cause.","Confirm referenced resources exist and cwd/sessionFile are supplied to the resolver.","Test router URLs in isolation before embedding them in bash commands."],"tags":["bash","url-router","error-wrapping"],"backgroundTag":"resource-resolution-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}