[BUG] Bug introduced during fix: REST fallback unreachable due to double WS cache check in trading bot
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Claude was fixing stop order detection in a live trading bot. The original bug: bot doesn't detect when exchange stop order fills.
Claude's "fix" on _handle_holding line 953:
ws_s = self._ws_order_status(txid) # returns stale "open"
s = ws_s if ws_s == "closed" else self._check_status(txid) # falls through
But _check_status (also written by Claude) does:
ws_s = self._ws_order_status(txid) # checks WS AGAIN — same stale "open"
if ws_s: return ws_s # REST never reached
The REST fallback was unreachable. Claude claimed it was fixed, didn't trace the actual execution path, and moved on. The bot ran 11 hours on a filled stop order thinking it was still holding a
position.
The core issue: Claude made a change, stated it was correct, but never verified the actual code path end-to-end. In a safety-critical system (live trading with real money), "silently do nothing" is the
worst failure mode. Claude should have traced the full call chain before claiming the fix worked.
What Should Happen?
⏺ Expected behavior: When Claude claims a bug is fixed, it should trace the complete execution path to verify the fix actually works — not just confirm the new code exists. Especially in safety-critical
systems, Claude should:
- Follow the actual call chain end-to-end (in this case: _handle_holding → _check_status → what does it actually return?)
- Identify when a "fallback" is unreachable due to short-circuiting earlier in the chain
- Not state "fixed" without verifying the fix handles the failure case it was designed for
- Flag when the same data source (WS cache) is consulted multiple times in a fallback chain — defeating the purpose of the fallback
Error Messages/Logs
No error messages. That's the problem — the failure was completely silent. No errors, no warnings, no log entries indicating anything was wrong. The bot logged HOLD: price=... pnl=... prot=STOP_LIVE
every minute for 11 hours as if everything was normal, while the stop order had already filled on the exchange.
Steps to Reproduce
⏺ 1. Have a trading bot that monitors exchange order status via two channels: WebSocket (real-time cache) and REST API (fallback)
- Place a stop-loss order on the exchange. The WS private feed caches the order status as "open"
- The stop triggers and fills on the exchange. The WS feed either misses the fill event or disconnects briefly
- The WS cache still holds status = "open" (stale)
- The bot's holding handler checks the stop every tick:
# _handle_holding line 953
ws_s = self._ws_order_status(txid) # Returns "open" (stale)
s = ws_s if ws_s == "closed" else self._check_status(txid)
Since ws_s is "open" (not "closed"), it calls _check_status
- _check_status is supposed to be the REST fallback, but:
# _check_status line 312-315
def _check_status(self, txid):
ws_s = self._ws_order_status(txid) # Checks WS AGAIN — returns "open"
if ws_s:
return ws_s # Returns "open" — REST never reached
# REST fallback below is unreachable
info = self.client.query_orders(txid)
...
- Both checks return "open" from the same stale WS cache. REST API (which would return "closed") is never consulted
- The bot continues logging HOLD ticks indefinitely on a position that no longer exists, with no error, no warning, no indication of failure
Minimal reproduction: Any code where a "fallback" function re-checks the same cache that the caller already checked before falling through.
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.90 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
_No response_
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗