{"record":{"id":"9449b27d2a3082a8","repo":"can1357/oh-my-pi","slug":"cannot-internalurlaction-internal-url-without-a","errorCode":null,"errorMessage":"Cannot ${internalUrlAction} internal URL without a backing file: ${rawPath}","messagePattern":"Cannot (.+?) internal URL without a backing file: (.+?)","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/path-utils.ts","lineNumber":1567,"sourceCode":"\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,\n\t\t\tsignal: opts.signal,\n\t\t\tsessionFile: opts.sessionFile,\n\t\t\tlocalProtocolOptions: opts.localProtocolOptions,\n\t\t\tskills: opts.skills,\n\t\t\t// Tool-scope resolution only needs `sourcePath`; skip content\n\t\t\t// materialization so large artifacts (or any handler that separates\n\t\t\t// path from content) stay searchable without OOM risk.\n\t\t\tpathOnly: true,\n\t\t});\n\t\tif (!resource.sourcePath) {\n\t\t\tthrow new ToolError(`Cannot ${internalUrlAction} internal URL without a backing file: ${rawPath}`);\n\t\t}\n\t\tif (opts.trackImmutableSources && resource.immutable) {\n\t\t\timmutableSourcePaths.add(path.resolve(resource.sourcePath));\n\t\t}\n\t\tresolvedPathInputs.push(resource.sourcePath);\n\t}\n\n\tlet missingPaths: string[] = [];\n\tlet effectivePaths = resolvedPathInputs;\n\tif (resolvedPathInputs.length > 1) {\n\t\tconst partition = await partitionExistingPaths(resolvedPathInputs, cwd, parseSearchPath);\n\t\tif (partition.valid.length === 0) {\n\t\t\tthrow new ToolError(`Path not found: ${partition.missing.join(\", \")}`);\n\t\t}\n\t\teffectivePaths = partition.valid;\n\t\tmissingPaths = partition.missing;\n\t}\n","sourceCodeStart":1549,"sourceCodeEnd":1585,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/path-utils.ts#L1549-L1585","documentation":"After the InternalUrlRouter resolves an internal URL in path-only mode, the resource must expose a `sourcePath` (a backing local file) for search tools to operate on. Resources whose content is generated in memory or held outside the filesystem cannot back a search scope, so this ToolError is thrown naming the action and URL.","triggerScenarios":"Calling search/ast_grep/ast_edit with an internal URL (e.g. some session://, agent://, or history:// resources) whose handler returns a resource without sourcePath when resolved with `pathOnly: true` in resolveToolSearchScope.","commonSituations":"Searching a virtual resource that only renders content on demand (e.g. a computed summary, an in-memory artifact) rather than one persisted to a file; handler updated to separate path from content so older consumers now hit the missing sourcePath.","solutions":["Use `read` on the internal URL to fetch its content and search the text directly instead of a file-backed scope search.","Target a resource variant that has a backing file (e.g. the persisted transcript rather than a computed view).","If you own the handler, materialize the resource to a file so sourcePath is populated for path-only resolution."],"exampleFix":"// before\nsearch({ pattern: \"panic\", paths: [\"agent://run-42/summary\"] }) // no backing file\n// after\nconst res = await read({ path: \"agent://run-42/summary\" });\nsearchInText(res.content, \"panic\");","handlingStrategy":"fallback","validationCode":"const resource = await internalRouter.resolve(p, { cwd, pathOnly: true });\nif (!resource.sourcePath) {\n  // use read + in-memory search instead of scope search\n}","typeGuard":"const hasBackingFile = (resource) => typeof resource?.sourcePath === \"string\" && resource.sourcePath.length > 0;","tryCatchPattern":"try { scope = await resolveToolSearchScope(opts); }\ncatch (e) {\n  if (e.message.includes(\"without a backing file\")) {\n    const res = await read({ path: p });\n    return searchInText(res.content, pattern);\n  }\n  throw e;\n}","preventionTips":["Resolve with pathOnly first and check sourcePath before choosing a search strategy.","Prefer persisted resource variants over computed/virtual views for search.","Keep handlers materializing content to disk when search support is expected."],"tags":["internal-url","search","missing-file","validation"],"backgroundTag":"resource-has-no-backing-file","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}