{"record":{"id":"078d7056b8a093e4","repo":"can1357/oh-my-pi","slug":"cannot-rewrite-external-url-rawpath-use-read","errorCode":null,"errorMessage":"Cannot rewrite external URL: ${rawPath}. Use `read` or `search` to inspect fetched web content; ast_edit only applies to local files.","messagePattern":"Cannot rewrite external URL: (.+?)\\. Use `read` or `search` to inspect fetched web content; ast_edit only applies to local files\\.","errorType":"validation","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/ast-edit.ts","lineNumber":298,"sourceCode":"\t\t\t\t\tthrow new ToolError(`Duplicate rewrite pattern: ${pat}`);\n\t\t\t\t}\n\t\t\t\tseenPatterns.add(pat);\n\t\t\t}\n\t\t\tconst normalizedRewrites = Object.fromEntries(ops);\n\t\t\tconst maxFiles = $envpos(\"PI_MAX_AST_FILES\", 1000);\n\n\t\t\tconst scope = await resolveToolSearchScope({\n\t\t\t\trawPaths: params.paths,\n\t\t\t\tcwd: this.session.cwd,\n\t\t\t\tinternalUrlAction: \"rewrite\",\n\t\t\t\tsettings: this.session.settings,\n\t\t\t\tsignal,\n\t\t\t\tsessionFile: this.session.getSessionFile() ?? undefined,\n\t\t\t\tlocalProtocolOptions: this.session.localProtocolOptions,\n\t\t\t\tskills: this.session.skills,\n\t\t\t\tresolveExternalUrl: async rawPath => {\n\t\t\t\t\tif (!parseReadUrlTarget(rawPath)) return undefined;\n\t\t\t\t\tthrow new ToolError(\n\t\t\t\t\t\t`Cannot rewrite external URL: ${rawPath}. Use \\`read\\` or \\`search\\` to inspect fetched web content; ast_edit only applies to local files.`,\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t});\n\t\t\tconst { searchPath: resolvedSearchPath, scopePath, isDirectory, multiTargets, globFilter } = scope;\n\n\t\t\tconst result = await runAstEditOnce(multiTargets, resolvedSearchPath, globFilter, {\n\t\t\t\trewrites: normalizedRewrites,\n\t\t\t\tdryRun: true,\n\t\t\t\tmaxFiles,\n\t\t\t\tfailOnParseError: false,\n\t\t\t\tsignal,\n\t\t\t});\n\n\t\t\tconst { errors: cappedParseErrors, total: parseErrorsTotal } = capParseErrors(result.parseErrors);\n\t\t\tconst formatPath = (filePath: string): string =>\n\t\t\t\tformatResultPath(filePath, isDirectory, resolvedSearchPath, this.session.cwd);\n","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/ast-edit.ts#L280-L316","documentation":"ast_edit only operates on local files. When a target path looks like an external URL (parseReadUrlTarget recognizes it), the resolveExternalUrl hook throws this ToolError directing the caller to `read` or `search` for inspecting fetched web content instead of rewriting it.","triggerScenarios":"Calling ast_edit with a path/target like `https://example.com/foo.ts` or another URL scheme that parseReadUrlTarget accepts as a web target.","commonSituations":"An LLM confusing the read tool's URL-fetch capability with ast_edit's scope; automations piping a previously fetched URL into edit tools; attempts to 'fix' remote code without downloading it first.","solutions":["Use a local filesystem path instead of a URL; ast_edit cannot modify remote content.","Fetch the content with the read tool (or download the file), edit the local copy, then re-upload/publish via the appropriate mechanism.","If the URL is actually a local file path misparsed as a URL (e.g. contains '://'), correct the path format."],"exampleFix":"// before\nawait astEdit.execute({ path: 'https://example.com/src/app.ts', ops });\n// after\nawait astEdit.execute({ path: 'src/app.ts', ops });","handlingStrategy":"validation","validationCode":"if (/^[a-z][a-z0-9+.-]*:\\/\\//i.test(path) || path.startsWith('http')) {\n  throw new Error('ast_edit accepts local paths only; fetch remote content first');\n}","typeGuard":"function isLocalPath(target: string): boolean {\n  return !/^[a-z][a-z0-9+.-]*:\\/\\//i.test(target);\n}","tryCatchPattern":"try {\n  await astEditTool.execute({ path, ops }, signal);\n} catch (err) {\n  if (err instanceof ToolError && err.message.startsWith('Cannot rewrite external URL')) {\n    // fall back to read/download the URL, then edit a local copy\n  }\n}","preventionTips":["Resolve URLs to local files before any edit-tool call.","Route remote content through the read/search tools, not edit tools.","Validate target paths look like filesystem paths in tool-calling pipelines."],"tags":["validation","url","ast-edit","local-files-only"],"backgroundTag":"external-url-not-supported","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}