What happened
An agent implementing PR feedback on #722 needed to read lib/store/userSkills.ts (1121 lines). The file exceeded the tool's default limit of 1000 lines, so the read was truncated to lines 1..1000.
The agent then:
- Tried increasing
maxBytes — doesn't help, the tool already returned all the bytes it could.
- Resorted to raw
sed via exec to edit the file — wrong tool for the job.
Neither was the correct approach.
What should have happened
The read_file tool has an offset parameter (1-based start line). The correct pattern:
read_file(path, offset=1, limit=1000) → lines 1..1000
read_file(path, offset=1001, limit=500) → lines 1001..1121 (full coverage)
The agent would then have a successful full read of the entire file and could use str_replace for surgical edits — the normal, safe workflow.
Why this matters
- The
offset parameter is documented in the tool description, but it's easy to overlook when the default behavior (truncation) looks like a protocol or size limit, not a pagination hint.
- An agent that misses
offset will either give up on a file entirely or resort to blind sed edits — both are worse than reading the file properly and using str_replace.
- This isn't a rare edge case: any file over ~1000 lines hits this, and the repo has several (
userSkills.ts at 1121, agentStream.test.ts at 1102, route.ts at 1013).
Possible mitigations
- Tool description wording — make the offset/pagination pattern more prominent, e.g. "To read beyond the default 1000-line limit, call again with offset=N+1."
- Return metadata when truncated — if
returnedLines < totalLines, include a note like [truncated at line 1000; file is 1121 lines total — use offset=1001 to continue]
- Persona standing orders — add a note that files >1000 lines need paginated reads.
Option 2 is probably the most robust: the tool already knows it truncated, but the agent only sees the last line number.
Likely scope
lib/tools/exec/handleReadFile.ts — if the result is truncated, append a metadata line like [File continues beyond line N — N+1 to end: use offset=N+1 to read the remaining M lines]
- Maybe a small test in
tools.test.ts
Discovered during
PR feedback round on #722 (plan/skill-followups-phase-2-3).
What happened
An agent implementing PR feedback on #722 needed to read
lib/store/userSkills.ts(1121 lines). The file exceeded the tool's defaultlimitof 1000 lines, so the read was truncated to lines 1..1000.The agent then:
maxBytes— doesn't help, the tool already returned all the bytes it could.sedviaexecto edit the file — wrong tool for the job.Neither was the correct approach.
What should have happened
The
read_filetool has anoffsetparameter (1-based start line). The correct pattern:The agent would then have a successful full read of the entire file and could use
str_replacefor surgical edits — the normal, safe workflow.Why this matters
offsetparameter is documented in the tool description, but it's easy to overlook when the default behavior (truncation) looks like a protocol or size limit, not a pagination hint.offsetwill either give up on a file entirely or resort to blindsededits — both are worse than reading the file properly and usingstr_replace.userSkills.tsat 1121,agentStream.test.tsat 1102,route.tsat 1013).Possible mitigations
returnedLines < totalLines, include a note like[truncated at line 1000; file is 1121 lines total — use offset=1001 to continue]Option 2 is probably the most robust: the tool already knows it truncated, but the agent only sees the last line number.
Likely scope
lib/tools/exec/handleReadFile.ts— if the result is truncated, append a metadata line like[File continues beyond line N — N+1 to end: use offset=N+1 to read the remaining M lines]tools.test.tsDiscovered during
PR feedback round on #722 (
plan/skill-followups-phase-2-3).