fix(weixin): distinguish ret=-2 'prepare failed' from genuine rate limit (#80125) - #80156
JonthanaHanh wants to merge 1 commit into
Conversation
iLink returns ret=-2 for both rate limits AND parameter errors. When errmsg is 'prepare failed', the real cause is a missing/invalid context_token (e.g. fresh account with no inbound messages yet), not frequency limiting. Previously this was unconditionally treated as a rate limit, opening a 30s circuit breaker and hiding the real cause. Now 'prepare failed' raises a descriptive RuntimeError immediately without triggering the rate-limit cooldown, so operators can see the actual problem and know to send an inbound message or re-pair. Fixes NousResearch#80125
|
Hi @JonthanaHanh — heads-up that this PR overlaps with #80152 (also open, fixing #80125 with the same approach: treat iLink ret=-2 + "prepare failed" as a missing/invalid context_token parameter error rather than a rate limit). #80152 is the more complete implementation (unit helper + 8 regression tests covering breaker-not-opened and fail-fast behavior, plus a token_dir hint in the error message), and it's been rebased on latest main. To land the fix once, I'll close this PR in favor of #80152 — happy to reconsider if you'd prefer to merge the changes here instead. Thanks for surfacing the same bug! |
|
Following up on the overlap note (no reply from the author yet). To keep the fix landing cleanly, this PR should be closed in favor of #80152 — it fixes the same bug (#80125) but with full coverage:
@JonthanaHanh @NousResearch/maintainers — recommend closing this as duplicate of #80152 so the fix lands once. Happy to rebase/merge either direction if the author prefers to keep theirs. |
|
Hi @JonthanaHanh — this PR and #80152 fix the same root cause (#80125: weixin Comparing the two objectively:
#80152 is the more complete fix (regression tests + helper abstraction) and already has CI running. Since I can't close a PR I don't own, I'd suggest we keep #80152 and close this one as duplicate — or if you prefer to keep this, let me know and I'll close mine. Either way, thanks for independently catching the same issue! |
…ion error, not a rate limit (NousResearch#80125) iLink answers a bot-initiated send with ret=-2 errmsg="prepare failed" when the peer's session is not ready (no inbound message yet, or the context token is gone). That is deterministic: treating it as a frequency limit spent the retry budget on an error that never clears and opened the 30 s rate-limit breaker for the whole account, blocking every later send (NousResearch#80125, NousResearch#112709). After the tokenless re-send (46ab37c) has been tried — or when there is no token to drop — a stale-session -2 now fails fast with a descriptive "session not ready" error and never reaches the rate-limit path. The text avoids the "rate limit" substring classify_send_error keys on. Salvage of NousResearch#80152 (fail fast + keep the breaker closed); NousResearch#80156 arrived five minutes later with the same change. Co-authored-by: RelaxJonh <92573950+RelaxJonh@users.noreply.github.com>
…ion error, not a rate limit (#80125) iLink answers a bot-initiated send with ret=-2 errmsg="prepare failed" when the peer's session is not ready (no inbound message yet, or the context token is gone). That is deterministic: treating it as a frequency limit spent the retry budget on an error that never clears and opened the 30 s rate-limit breaker for the whole account, blocking every later send (#80125, #112709). After the tokenless re-send (46ab37c) has been tried — or when there is no token to drop — a stale-session -2 now fails fast with a descriptive "session not ready" error and never reaches the rate-limit path. The text avoids the "rate limit" substring classify_send_error keys on. Salvage of #80152 (fail fast + keep the breaker closed); #80156 arrived five minutes later with the same change. Co-authored-by: RelaxJonh <92573950+RelaxJonh@users.noreply.github.com>
…ion error, not a rate limit (NousResearch#80125) iLink answers a bot-initiated send with ret=-2 errmsg="prepare failed" when the peer's session is not ready (no inbound message yet, or the context token is gone). That is deterministic: treating it as a frequency limit spent the retry budget on an error that never clears and opened the 30 s rate-limit breaker for the whole account, blocking every later send (NousResearch#80125, NousResearch#112709). After the tokenless re-send (46ab37c) has been tried — or when there is no token to drop — a stale-session -2 now fails fast with a descriptive "session not ready" error and never reaches the rate-limit path. The text avoids the "rate limit" substring classify_send_error keys on. Salvage of NousResearch#80152 (fail fast + keep the breaker closed); NousResearch#80156 arrived five minutes later with the same change. Co-authored-by: RelaxJonh <92573950+RelaxJonh@users.noreply.github.com> (cherry picked from commit bd39167)
Summary
iLink returns
ret=-2for both rate limits AND parameter errors. Whenerrmsgis"prepare failed", the real cause is a missing/invalidcontext_token(e.g. fresh account with no inbound messages yet), not frequency limiting.Previously this was unconditionally treated as a rate limit, opening a 30s circuit breaker and hiding the real cause behind "iLink sendmessage rate limited; cooldown active for 30.0s".
Changes
In
_send_text_chunk_locked(gateway/platforms/weixin.py), added a check before the generic rate-limit handler:ret=-2+errmsg="prepare failed"raises a descriptiveRuntimeErrorimmediately: "iLink sendmessage parameter error: prepare failed (likely missing context_token -- user must send an inbound message first or re-pair)"ret=-2with other errmsg values) continue to work as beforeImpact
errmsg="unknown error") and genuine rate limits are unchangedFixes #80125