CCD CycleHealth crashes with "undefined is not an object (evaluating '$.input_tokens')" on API errors
Summary
When an API call fails mid-conversation (network hiccup, rate limit, etc.), the CCD CycleHealth component tries to read $.input_tokens from the error response. Error responses don't carry usage stats, so $ is undefined and the read throws — surfacing as "Turn failed / Try sending your message again."
Environment
- App version: 1.7196.3 (Windows desktop)
- OS: Windows 11 Enterprise 10.0.26200
- Platform: win32 x64
- Node: 24.15.0
Log evidence
From %APPDATA%\Claude\logs\main.log:
2026-05-19 07:42:07 [info] [CCD CycleHealth] unhealthy cycle for local_324985da-... (19s, hadFirstResponse=true, reason=api_error)
2026-05-19 07:42:07 [warn] [CCD CycleHealth] local_324985da-... api_error (success): undefined is not an object (evaluating '$.input_tokens')
Multiple occurrences across sessions, both on 1.7196.0 and 1.7196.3:
2026-05-18 11:32:38 [warn] [CCD CycleHealth] ... api_error (success): undefined is not an object (evaluating '$.input_tokens')
2026-05-19 07:16:48 [warn] [CCD CycleHealth] ... api_error (success): undefined is not an object (evaluating '$.input_tokens')
2026-05-19 07:18:36 [warn] [CCD CycleHealth] ... api_error (success): undefined is not an object (evaluating '$.input_tokens')
2026-05-19 07:25:25 [warn] [CCD CycleHealth] ... api_error (success): undefined is not an object (evaluating '$.input_tokens')
2026-05-19 07:42:07 [warn] [CCD CycleHealth] ... api_error (success): undefined is not an object (evaluating '$.input_tokens')
Root cause (likely)
The CycleHealth error handler reads $.input_tokens (or destructures { input_tokens } from a usage/response object) without guarding against the case where the API returns an error response rather than a successful streaming response. Error responses don't include a usage block.
Expected behavior
The error handler should guard against undefined usage data:
// e.g.:
const inputTokens = $?.input_tokens ?? 0;
Or check response type before accessing usage fields.
Workaround
Retrying the failed turn succeeds in most cases. The bug only fires when an underlying API error occurs; it's a secondary crash on top of the real failure.
Sentry
Already being reported automatically via Sentry — event IDs visible in local logs (e.g. 0f187b836806476b9c930aad9647485a).
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗