[BUG] Crash with "undefined is not an object (evaluating 'T.input_tokens')" when spawning parallel sub-agents via Agent tool
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?
When the Agent tool is used to spawn two or more sub-agents in a single message
(parallel invocation), the first agent crashes immediately with:
undefined is not an object (evaluating 'T.input_tokens')
The second agent fails with a cascading error:
Sibling tool call errored
This occurs in an environment where Claude Code communicates through a corporate
API Gateway, which acts as a black box between Claude Code and the Anthropic API.
The gateway may transform, filter, or reshape API responses — meaning the usage
object returned to Claude Code may not always match the expected schema.
Claude Code's token-counting function cDR() does not defensively handle a usage
object where input_tokens is present as an object but its fields are undefined,
causing an unrecoverable crash during sub-agent spawning.
---
The crash site is the cDR() function (context window usage % calculator):
function cDR(T, R) {
if (!T) return { used: null, remaining: null };
// ⚠️ No field-level null check — crashes if T.input_tokens is undefined
let A = T.input_tokens + T.cache_creation_input_tokens + T.cache_read_input_tokens,
...
}
The guard if (!T) only handles T being null/undefined entirely.
It does NOT handle the case where T is a valid object but individual fields
(input_tokens, cache_creation_input_tokens, etc.) are missing or undefined.
In environments behind a corporate API Gateway — which is a black box that may
alter response shapes — this assumption is unsafe. The usage object may arrive
with a different structure than what the Anthropic API directly returns.
Other token-tracking code in the same binary applies proper defensive patterns:
B.input_tokens + (B.cache_creation_input_tokens ?? 0) + ...
AT.input_tokens || 0
But cDR() is inconsistently undefended, making it a fragile point of failure
when responses pass through any intermediate layer that could reshape usage data.
Suggested fix — apply null-coalescing inside cDR():
let A = (T.input_tokens ?? 0)
- (T.cache_creation_input_tokens ?? 0)
- (T.cache_read_input_tokens ?? 0)
What Should Happen?
Both sub-agents should spawn successfully and return their results independently.
Parallel agent invocation should be supported without crashing.
Error Messages/Logs
undefined is not an object (evaluating 'T.input_tokens')
Sibling tool call errored
Steps to Reproduce
- In a Claude Code session, ask Claude to handle a request that triggers parallel sub-agent spawning
(e.g., two independent research tasks in one message).
- Claude invokes the Agent tool twice in the same message block (parallel tool calls).
- The first Agent tool call returns:
undefined is not an object (evaluating 'T.input_tokens')
- The second Agent tool call returns:
Sibling tool call errored
Minimal example prompt that triggers this:
"Look up how ad serving works AND how coupon discount is calculated."
This causes Claude to spawn two independent sub-agents simultaneously,
which reliably reproduces the crash.
---
Root Cause (from binary analysis)
By extracting strings from the Claude Code binary (~/.local/bin/claude),
the following function was identified as the crash site:
function cDR(T, R) {
if (!T) return { used: null, remaining: null };
// ⚠️ Crashes here if T exists but T.input_tokens is undefined
let A = T.input_tokens + T.cache_creation_input_tokens + T.cache_read_input_tokens,
_ = Math.round(A / R * 100),
B = Math.min(100, Math.max(0, _));
return { used: B, remaining: 100 - B };
}
The guard if (!T) only handles the case where T is falsy (null/undefined).
It does NOT handle the case where T is a valid object but T.input_tokens is undefined —
which appears to happen when a sub-agent's API response returns a usage object
with a missing or differently-shaped input_tokens field.
Other token-counting code in the same binary uses safe access patterns:
T.cumulativeInputTokens += B.input_tokens + (B.cache_creation_input_tokens ?? 0) + ...
J[IT].inputTokens += AT.input_tokens || 0
The fix would be to apply the same null-coalescing pattern inside cDR():
let A = (T.input_tokens ?? 0) + (T.cache_creation_input_tokens ?? 0) + (T.cache_read_input_tokens ?? 0)
Claude Model
Sonnet (default)
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.66
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
_No response_
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗