anomalyco / anomalyco/opencode

grep tool searches the whole parent directory when path points to a file

Open
#45,185 1 comment 0 reactions 1 assignee View on GitHub

@rekram1-node is already working on this.

Since Aug 26, 2026.

Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

Description

When the grep tool is given a path that points to a file, it silently searches that file's entire parent directory instead.

packages/opencode/src/tool/grep.ts:

const search = FSUtil.resolve(requested)
const info = yield* fs.stat(search).pipe(Effect.catch(() => Effect.succeed(undefined)))
const cwd = info?.type === "Directory" ? search : path.dirname(search)
const result = yield* ripgrep.grep({
  cwd,
  pattern: params.pattern,
  include: params.include,
  limit: 100,
})

The info?.type === "Directory" ? … : path.dirname(search) branch shows the file case is anticipated — but once cwd has been widened to the parent directory nothing narrows the search back down, so ripgrep is invoked over every file in that directory.

The Ripgrep service already supports scoping to a single file. GrepInput declares it and the implementation passes it as ripgrep's path argument (packages/core/src/ripgrep.ts):

export interface GrepInput {
  readonly cwd: string
  readonly pattern: string
  readonly file?: string
  readonly include?: string
  readonly limit: number
  readonly signal?: AbortSignal
}
"--",
input.pattern,
input.file ?? ".",

The v2 tool in packages/core/src/tool/grep.ts:97-104 uses it correctly:

.grep({
  cwd: info?.type === "Directory" ? target : path.dirname(target),
  pattern: input.pattern,
  file: info?.type === "File" ? path.basename(target) : undefined,
  include: input.include,
  limit: input.limit ?? Number.MAX_SAFE_INTEGER,
})

The tool wired into the CLI registry (packages/opencode/src/tool/registry.ts imports GrepTool from ./grep) is the one that omits file. file currently has no callers anywhere in the repo.

Consequences: the model asks about one file and receives matches from every sibling file, the 100-match limit is consumed by unrelated results, and a large directory turns a scoped lookup into a full scan.

Steps to reproduce
  1. grep with pattern set to something that appears in several files in a directory.
  2. Set path to one specific file in that directory.
  3. The output contains matches from the other files as well.
Operating System

Windows 11 (platform independent)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.