[BUG] Crash with "undefined is not an object (evaluating 'T.input_tokens')" when spawning parallel sub-agents via Agent tool

Resolved 💬 1 comment Opened Mar 4, 2026 by namsoo2 Closed Mar 5, 2026

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

  1. 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).

  1. Claude invokes the Agent tool twice in the same message block (parallel tool calls).
  1. The first Agent tool call returns:

undefined is not an object (evaluating 'T.input_tokens')

  1. 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_

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗