{"record":{"id":"d1ea8031deb9cc62","repo":"can1357/oh-my-pi","slug":"cannot-internalurlaction-external-url-rawpat","errorCode":null,"errorMessage":"Cannot ${internalUrlAction} external URL: ${rawPath}. Use \\`read\\` to fetch web content, then search the returned text.","messagePattern":"Cannot (.+?) external URL: (.+?)\\. Use \\\\`read\\\\` to fetch web content, then search the returned text\\.","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/path-utils.ts","lineNumber":1538,"sourceCode":"\t\t\ttry {\n\t\t\t\tawait fs.promises.stat(resolveToCwd(rawPath, cwd));\n\t\t\t} catch (err) {\n\t\t\t\texternalUrl = isEnoent(err) || isEnotdir(err);\n\t\t\t}\n\t\t}\n\t\tif (externalUrl) {\n\t\t\tconst resolved = opts.resolveExternalUrl ? await opts.resolveExternalUrl(rawPath) : undefined;\n\t\t\tif (resolved) {\n\t\t\t\tresolvedPathInputs.push(resolved.sourcePath);\n\t\t\t\tif (opts.trackImmutableSources && resolved.immutable) {\n\t\t\t\t\timmutableSourcePaths.add(path.resolve(resolved.sourcePath));\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// Resolver missing or declined (e.g. ftp/ws/wss): fail explicitly\n\t\t\t// instead of letting the local-path fallthrough surface a confusing\n\t\t\t// \"Path not found\" for a URL-shaped input.\n\t\t\tthrow new ToolError(\n\t\t\t\t`Cannot ${internalUrlAction} external URL: ${rawPath}. Use \\`read\\` to fetch web content, then search the returned text.`,\n\t\t\t);\n\t\t}\n\t\tif (!internalRouter.canHandle(rawPath)) {\n\t\t\tresolvedPathInputs.push(rawPath);\n\t\t\tcontinue;\n\t\t}\n\t\tif (isSshUrl(rawPath)) {\n\t\t\tthrow new ToolError(\n\t\t\t\t`Cannot ${internalUrlAction} a remote ssh:// path (no local file): ${rawPath}. Use \\`read ${rawPath}\\` to view it, or use \\`grep\\` on a specific remote file.`,\n\t\t\t);\n\t\t}\n\t\tif (hasGlobPathChars(rawPath)) {\n\t\t\tthrow new ToolError(`Glob patterns are not supported for internal URLs: ${rawPath}`);\n\t\t}\n\t\tconst resource = await internalRouter.resolve(rawPath, {\n\t\t\tcwd,\n\t\t\tsettings: opts.settings,","sourceCodeStart":1520,"sourceCodeEnd":1556,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/path-utils.ts#L1520-L1556","documentation":"When a rawPath matches a strict external URL scheme (http/https/ftp/ws/wss) but no external-URL resolver is configured or the resolvers decline it (e.g. ftp/ws/wss have none), resolveToolSearchScope throws this ToolError instead of letting the fallthrough produce a misleading 'Path not found'. Searching remote URLs directly is not supported for that scheme.","triggerScenarios":"Calling search/ast_grep with a scope entry like `https://example.com/data` or `ftp://host/file` while `resolveExternalUrl` is not provided (or returns undefined for that scheme) and internalUrlAction is e.g. `search`.","commonSituations":"Agent tries to grep a web page or API endpoint directly; user pastes a URL into the search tool's path parameter; ftp/ws URLs which the library deliberately does not materialize.","solutions":["Use the `read` tool on the URL to fetch its content, then run search/grep on the returned text or on the materialized local file.","For https URLs with a resolver available, ensure the caller wires `resolveExternalUrl` into resolveToolSearchScope options.","If the content exists locally, reference the local file path instead of the remote URL."],"exampleFix":"// before\nsearch({ pattern: \"TODO\", paths: [\"https://example.com/page.html\"] })\n// after\nconst page = await read({ path: \"https://example.com/page.html\" });\nsearchInText(page.content, \"TODO\");","handlingStrategy":"fallback","validationCode":"const EXTERNAL_URL_RE = /^(?:https?|ftp|ws|wss):\\/\\//i;\nif (EXTERNAL_URL_RE.test(p)) {\n  // route to read-then-search instead of search-scope resolution\n}","typeGuard":"const isExternalUrl = (p) => /^(?:https?|ftp|ws|wss):\\/\\//i.test(p);","tryCatchPattern":"try { scope = await resolveToolSearchScope(opts); }\ncatch (e) {\n  if (String(e.message).startsWith(\"Cannot \") && e.message.includes(\"external URL\")) {\n    const page = await read({ path: url });\n    return searchInText(page.content, pattern);\n  }\n  throw e;\n}","preventionTips":["Detect http(s)/ftp/ws URLs before calling search tools and use read first.","Only expect direct URL searching when resolveExternalUrl is wired up.","Remember ftp/ws/wss are deliberately unsupported for search scopes."],"tags":["url","search","unsupported-scheme","network"],"backgroundTag":"unsupported-url-scheme","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}