anomalyco / anomalyco/opencode

read tool accepts limit: 0 and answers with a hint that repeats the same call

Open
#45,200 0 comments 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
Avg merge
7h 2m
Merged PRs (30d)
384

Description

Description

The read tool declares offset and limit as NonNegativeInt, so 0 is accepted. Passing limit: 0 puts the model into a retry loop it cannot escape.

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

offset: Schema.optional(NonNegativeInt).annotate({
  description: "The line number to start reading from (1-indexed)",
}),
limit: Schema.optional(NonNegativeInt).annotate({
  description: "The maximum number of lines to read (defaults to 2000)",
}),

With limit: 0:

  • params.limit ?? DEFAULT_READ_LIMIT keeps 0?? only falls back on null/undefined, so the 2000 default does not apply.
  • In lines(), if (raw.length >= opts.limit) is 0 >= 0 on the very first line, so more is set and no line is ever pushed.
  • Back in run(), last = file.offset + file.raw.length - 1 is 1 + 0 - 1 = 0, and next = last + 1 = 1.

So the model receives no content and this hint:

(Showing lines 1-0 of 250. Use offset=1 to continue.)

offset=1 is the call it just made. Following the instruction reproduces the identical request, and nothing in the response signals that limit was the problem.

offset: 0 is accepted too and silently coerced to 1 by params.offset || 1, which contradicts the field's own "1-indexed" description.

The v2 tool already rejects both

packages/core/src/tool/read-filesystem.ts:

export const PageInput = Schema.Struct({
  offset: PositiveInt.pipe(Schema.optional),
  limit: PositiveInt.check(Schema.isLessThanOrEqualTo(MAX_READ_LINES)).pipe(Schema.optional),
})

PositiveInt excludes 0, so the v2 path returns a schema error the model can see and correct. The registered v1 tool accepts the value and produces the degenerate response instead.

Changing NonNegativeInt to PositiveInt in the v1 parameters would match that and turn a silent loop into a visible, correctable error.

Steps to reproduce
  1. Call read on any file with more than one line, passing limit: 0.
  2. The output contains no lines and ends with (Showing lines 1-0 of N. Use offset=1 to continue.).
  3. Following that hint issues the same call again.
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.