Repository navigation
toValue: keep the exact digits of large integer IDs in text results - #88
Conversation
Co-authored-by: Gabe <gpavanello@thefork.com>
JSON.parse rounds an integer it cannot store. Return those digits as text, including from a saved JSON file. Version 0.12.20. Co-authored-by: Gabe <gpavanello@thefork.com>
|
@greptile review |
[Medium impact] The change reaches programs that receive MCP tool results through code-mode. The PR appears safe to merge, with a non-blocking edge case where non-JSON text becomes an object. Findings
Fix with agent prompt### Issue 1
hooks/protocol.ts:194
`parseToolJson` rewrites `{9007199254740993:1}` as `{"9007199254740993":1}` because the scanner quotes the unquoted numeric key. `toValue` then returns an object instead of the original text. Programs that expect to read or return that text receive a different type.
Keep invalid JSON unchanged, and add a regression test for this case.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
|
| return parts.join('') | ||
| } | ||
|
|
||
| const parseToolJson = (text: string): unknown => JSON.parse(quoteUnsafeIntegers(text)) |
There was a problem hiding this comment.
Non-JSON text becomes an object
parseToolJson rewrites {9007199254740993:1} as {"9007199254740993":1} because the scanner quotes the unquoted numeric key. toValue then returns an object instead of the original text. Programs that expect to read or return that text receive a different type.
Keep invalid JSON unchanged, and add a regression test for this case.
Knowledge Base Used: Tool dispatch and protocol
Prompt To Fix With AI
This is a comment left during a code review.
Path: hooks/protocol.ts
Line: 194
Comment:
**Non-JSON text becomes an object**
`parseToolJson` rewrites `{9007199254740993:1}` as `{"9007199254740993":1}` because the scanner quotes the unquoted numeric key. `toValue` then returns an object instead of the original text. Programs that expect to read or return that text receive a different type.
Keep invalid JSON unchanged, and add a regression test for this case.
**Knowledge Base Used:** [Tool dispatch and protocol](https://app.greptile.com/gabe4coding/-/custom-context/knowledge-base/gabe4coding/claude-code-mode/-/docs/tool-dispatch-and-protocol.md)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.There was a problem hiding this comment.
Invalid JSON stays invalid: JSON.parse runs first, and the digit scan runs only after that parse succeeds, so {9007199254740993:1} comes back as the original text. Fixed in 43ed86f.
JSON.parse runs first. The digit scan runs only after that parse succeeds, so an unquoted key stays the original text. Co-authored-by: Gabe <gpavanello@thefork.com>
For Gabe
Why: a text tool result rounds an integer ID above 2^53, so a later call can use a different ID.
Risk: R1, review the items below. A large ID arrives as text, so a program that expects a number sees a string. Invalid JSON stays the original text.
Prior work: no earlier issue or pull request.
toValuehas usedJSON.parsesinced73f18f. Greptile round 1 (unquoted key) is fixed in 43ed86f.Intent
A tool result that is JSON text gives a program a wrong ID. The parse rounds an integer above 2^53. Keep the exact digits of that integer. Leave every other JSON value as the parse leaves it.
Not in scope: structured content, the program's own return value, decimals and exponents.
%%{init: {'theme': 'neutral'}}%% flowchart TD A[Tool text] --> B{"Has structured content?"} B -->|yes| C[Give that value] B -->|no| D{"Text parses as JSON?"} D -->|no| E[Give the text] D -->|yes| F{"Unquoted integer lost digits?"} F -->|yes| G[Give the digits as text] F -->|no| H[Give the parsed value]Risk
R1 (review the items below): Tool results that are JSON text now keep inexact integers as exact digit text.
ℹ️ 4 items need you: 4 validation gaps. Open to see them.
Validation gaps
Note
No
RISK.md: the level uses the defaults. Run skillpuredori:risk-initto set your rules.Drift
Asked: issue 85
✅ Checked against the intent: no drift.
Decisions
Reach
toValueinhooks/register.tsxCODING_STANDARDS.mdshapeOfnames string and number apartRollout and rollback
Evidence
toValuenumber 1234567890123456800string "1234567890123456789"{"id":1234567890123456800}{"id":"1234567890123456789"}9007199254740993in an array[9007199254740992]["9007199254740993"]"12345678901234567890""12345678901234567890"{"9007199254740993":1}on a0d78ef2.98 ms2.90 ms2.37 ms10.71 msℹ️ Full run output.
Reading map
ℹ️ 4 files, 2 to read first. Open to choose what to read.
%%{init: {'theme': 'neutral'}}%% flowchart TD f1["1 · plugin.json<br/>config"] f2["2 · usage.mdx"] f3["3 · protocol.ts<br/>shared code, public API"] --> f4["4 · code-mode.test.ts<br/>tests changed"]docs/usage.mdxStack
Step 1/1. Previous: none. Next: none.
Closes #85
Story
A text tool result rounds an integer ID above 2^53, so the program can call the wrong row. Keep the exact digits of that integer, and leave every other JSON value as the parse leaves it.
Not in scope: structured content, the program's own return value, decimals and exponents.