fix: keep the retry interval in the human message #12

Merged
jlxq0 merged 1 commit from fix/keep-the-retry-sentence into main 2026-09-02 02:36:27 +00:00
Owner

A regression I introduced in #10 and found by running the production check rather than by reasoning about the diff.

0.4.1 collapsed the local rate limit's human message into its machine code. structured_error took one string and used it for both the JSON-RPC message and data.code, so a message that had been a sentence became a token. Read off the deployed binary, ninety concurrent count_workouts against production:

{"code":-32029,"message":"rate_limited","data":{"class":"rate_limited","code":"rate_limited"}}

It used to be "rate limit exceeded; try again in a minute".

The class and the code are correct and a caller matching data.class is unaffected, which is why every test passed. What was lost is the sentence a human reads in a log, and with it the only place the retry interval is stated anywhere in the response.

structured_error now takes the condition and the message separately.

The test that would have caught it

message.contains("minute")                     the interval is still stated
message != data.code                           it has not collapsed into the token

Verified by removal. Collapsing them again turns a_rate_limit_never_arrives_as_an_empty_read red and quotes the message back:

the retry interval is gone from the human message: "rate_limited"

Worth naming as a class: the tests from #10 assert the machine-readable fields, because those were the defect. A human-readable field with nothing asserting it is free to degrade under a refactor that is correct about everything a test looks at, and that is exactly what happened here, one release later, in the change that added the tests.

Verification

Gates on 1.98.0 through the build slot: fmt, clippy, test (48 passed), audit, deny.

**A regression I introduced in #10 and found by running the production check rather than by reasoning about the diff.** `0.4.1` collapsed the local rate limit's human message into its machine code. `structured_error` took one string and used it for both the JSON-RPC `message` and `data.code`, so a message that had been a sentence became a token. Read off the deployed binary, ninety concurrent `count_workouts` against production: ``` {"code":-32029,"message":"rate_limited","data":{"class":"rate_limited","code":"rate_limited"}} ``` It used to be `"rate limit exceeded; try again in a minute"`. The class and the code are correct and a caller matching `data.class` is unaffected, which is why every test passed. What was lost is the sentence a human reads in a log, and with it the only place the retry interval is stated anywhere in the response. `structured_error` now takes the condition and the message separately. ## The test that would have caught it ``` message.contains("minute") the interval is still stated message != data.code it has not collapsed into the token ``` Verified by removal. Collapsing them again turns `a_rate_limit_never_arrives_as_an_empty_read` red and quotes the message back: ``` the retry interval is gone from the human message: "rate_limited" ``` **Worth naming as a class**: the tests from #10 assert the machine-readable fields, because those were the defect. A human-readable field with nothing asserting it is free to degrade under a refactor that is correct about everything a test looks at, and that is exactly what happened here, one release later, in the change that added the tests. ## Verification Gates on 1.98.0 through the build slot: `fmt`, `clippy`, `test` (48 passed), `audit`, `deny`.
fix: keep the retry interval in the human message
All checks were successful
CI / cargo (pull_request) Successful in 41s
CI / docker (pull_request) Successful in 49s
aa1df44fd4
0.4.1 collapsed the local rate limit's message into its machine code. It
had been 'rate limit exceeded; try again in a minute' and became the
bare token 'rate_limited', because structured_error used one string for
both the JSON-RPC message and data.code. Measured on the deployed
binary, not inferred:

  {"code":-32029,"message":"rate_limited",
   "data":{"class":"rate_limited","code":"rate_limited"}}

The class and the code are right and a caller is unaffected. What was
lost is the sentence a human reads in a log, and with it the only place
the retry interval was stated.

structured_error now takes the condition and the message separately, and
a test pins the message: it must contain the interval and must not equal
data.code. Collapsing them again turns it red, quoting the message.

Nothing else changes. 0.4.2.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NCiHcHN6LrhiuLXbG9SBYG
jlxq0 merged commit 99a213b529 into main 2026-09-02 02:36:27 +00:00
jlxq0 deleted branch fix/keep-the-retry-sentence 2026-09-02 02:36:28 +00:00
Sign in to join this conversation.
No reviewers
No labels
waiting-on-julian
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
jlxq0/hevy-mcp!12
No description provided.