Tech 10 min read

Claude Code 'court' bug: tool calls leak as text instead of running (Opus 4.8)

IkesanContents

Claude Code prints just court right before it tries to call a tool and stops, or it shows <invoke name="..."> as literal text after court and nothing runs.
This isn’t only your local shell or MCP server jamming up — there are multiple reports of the same shape filed as Claude Code issues.

This is a bit different from the case where it hangs after Bash, Read, or Edit has already run.
The shape of the problem is that at the stage of building the tool call, it doesn’t become a structured tool_use and leaks into the conversation as plain text.
From the Claude Code harness’s point of view there’s no executable tool call, so to the user it looks like “nothing ran and it stalled.”

If you run long sessions parked in tmux, watch for this symptom as an extension of How do you manage Claude Code sessions? that I wrote before.
Keeping sessions around is convenient, but in this batch of issues, high context, multi-day resumes, and lots of Edit/Read/Bash keep showing up as triggers.

Raw invoke with court shows up verbatim

The representative one is GitHub Issue #64108.
The reporter writes that in a long Claude Code CLI session, Edit and Read calls didn’t execute and text like the following was shown verbatim.

court
<invoke name="Edit">
<parameter name="file_path">/path/to/file</parameter>
...
</invoke>

In comments on the same issue there’s a follow-up report that court appeared 182 times in an Opus 4.8 1M session, and another that the same shape appeared 490 times on Opus 4.7 + Claude Code 2.1.148.
So there’s nothing here to claim it’s “only Opus 4.8” or “only Claude Code 2.1.158 and later.”
That said, across the issue list, reports involving Opus 4.8 and long sessions stand out from late May into early June.

#64150 is close to the “repeats the same breakage without executing” symptom I hit locally.
On Opus 4.8’s 1M context, the tool call gets court prepended, the namespace drops, the block is shown as text, and the tool doesn’t run.
Even after the user said “that just came out as text, nothing actually ran,” the reporter writes it repeated the same breakage about 10 times.

#65705 makes the symptom even clearer.
The assistant message’s stop_reason becomes end_turn, and a court-prefixed <invoke name="Bash"> ends up in the body.
In that case the harness has no tool_use block to execute.
So the command doesn’t fail — it just never runs in the first place.

It’s not that the tool is heavy — the call’s shape is broken

If you loosely call the symptom “Claude Code hung,” the list of possible causes gets too wide.
This court family is, at least in the issue reports, treated as a serialization break of the tool call.

The difference is easy to isolate locally.

What you see on screenClosest cause
Doesn’t come back after Bash execution logs appearcommand, subprocess, stream, timeout
Freezes without an approval prompt appearingpermission prompt, UI renderer
court and <invoke name="..."> show up as prosebroken tool_use generation
tool call could not be parsed appearstool-call parser or model output

When court shows up, restarting the MCP server sometimes doesn’t fix it.
The output is broken before execution, so the request never reached the server side.

In early June the official status side was rough too

On Anthropic’s status page, from June 1 to 7, 2026, incidents for Opus 4.7, Opus 4.8, Sonnet 4.6, multiple models, and Claude Code services line up.
In the June 3 Claude Code services incident, Claude Code security reviews, code reviews, routines, and some Claude Code web sessions were recorded as degraded.
On June 5 many Claude models had elevated errors, on June 6 Opus 4.8 had elevated errors and degraded service, and on June 7 several models had degraded performance.

The impact showed up outside Anthropic too. Notion’s status page logged the Opus 4.7 and 4.8 degradation as a June 5–7 incident.
Because the failure rate rose for Notion AI users who picked those models, Notion writes that it temporarily disabled all Anthropic models in its model picker and routed requests to other providers.
That’s an outside service treating it as an Opus 4.7/4.8-side problem and acting on it, not a user misconfiguration.

This isn’t grounds to tie the cause of the court issue directly to an official outage.
But it’s a fact that model-side and Claude Code-side errors ran back to back in the same week.
Rather than writing it off as “only my machine is broken,” it’s faster to line up the timestamps on the status page and the GitHub issues.

April’s Claude Code quality postmortem sits in a nearby context.
Anthropic explains that the March 4 reasoning effort change, the March 26 thinking-history deletion bug, and the April 16 system prompt change affected Claude Code quality.
That article also touched on reports where long latency at high effort made the UI look frozen.

This court isn’t written up as the same bug as those three in the April postmortem.
But in that long sessions, thinking history, tool calls, and a sense of UI stall are all involved, it shows up on the same operational surface.

To check locally, look at the jsonl

Claude Code’s local sessions are kept in JSONL under ~/.claude/projects/.
A comment on Issue #64108 had an example of grepping for the shape where the assistant message is stop_reason: "tool_use" but the content is just court with no tool_use block.

Locally, I look at these first.

  • Did just court appear on screen
  • Did <invoke name="Bash"> or <invoke name="Edit"> show up as prose
  • Right after that, is there an actual file change, command execution, or MCP server-side log
  • Is stop_reason tool_use while there’s no tool_use block
  • Is it stop_reason=end_turn with <invoke name= in the body

If there are no execution logs here, deciding to throw the session away before diving into Bash or MCP debugging is the faster call.
If you say “do it again” in the same conversation, it can step on the broken <invoke> as the template for its next output.
The #64150 report also writes that it repeated the same breakage after the user pointed it out.

What happens after court

In GitHub issues, the full text of <invoke name="..."><parameter name="..."> showing up verbatim is common.
But when you actually hit it locally, breaking that cleanly is rarer.

The most common one is the pattern where, after court, only the Bash tool-call header is shown and nothing executes.
The screen shows it trying to call Bash.
The command doesn’t run, no result comes back, and it just stops.
It’s also different from the state where no approval prompt is shown.
Looking at the local process list, no Bash child process has started either.

In issue reports there are cases where even the <parameter name="command"> tag is shown as text, but locally the <parameter> tag has never leaked out for me.
court → Bash header → silence was nearly all of it.
There are stages to how it breaks: the whole XML structure falling into text like in the issue reports is a fairly advanced state, and in terms of how often you actually run into it, the form where only the Bash header shows and goes quiet is far more common.

Locally, it comes out like this.

⏺ Moving on to check the output. Generating 4 and looking at how each turned out.

court

✻ Brewed for 45s · 2 shells still running

❯ actually run it

⏺ court

✻ Cooked for 10s · 2 shells still running

❯ it stalled again, keep going

⏺ Bash(cd ~/project && python gen.py ...)
  saved out_01.png

⏺ Got 4. Checking each.

court

  Read 3 files

⏺ The first one is off from what I expected. Re-reading so I don't misread it.

court

  Read 1 file

⏺ The tool call shifted and the read offset moved. Re-reading to pin it down.

court

As you can see, court shows up right before a tool call every time, at the boundary where it moves from text to Bash or Read.
As the ✻ Brewed for 45s · 2 shells still running line shows, the background shells are still running, so what’s stuck is only the session’s tool-call generation.

If you prod it loosely with “resume” or “go” in this state, the next turn generates a normal tool_use and the command runs too.
But it’s not fixed — after a few more tool calls it breaks the same way again.
It moves when you say “go,” but the root cause hasn’t changed.

With the previous turn’s broken output in context, when a “resume” message gets inserted the model rebuilds the tool-call structure from scratch.
So the next single call goes through.
The broken context itself doesn’t disappear, so after a while it breaks again.
The reporter in Issue #64150 writing “it repeated the same breakage 10 times” is the result of this cycle going on and on.

The moment you see court, tool calls in that session have become unstable.
Rather than trusting the one call that went through on “go” and continuing with file edits or git operations, cutting the session is safer.

The workaround is to keep sessions short

There’s no confirmed fix on the GitHub issues yet.
What you can do locally comes down to not keeping a broken session alive.

Dropping the model is an option, but escaping to Opus 4.7 for the court problem is a poor trade.
Opus 4.7 has its own reported habit of skipping tool calls — the Opus 4.8 release notes mention fixing exactly that — and Notion disabling all Anthropic models rather than switching to 4.7 reflects that both 4.7 and 4.8 were off.
If you stay on Claude, Sonnet 4.6 is steadier, though it’s still not a confirmed fix for court itself.

When court shows up in a long session, move to a new session first.
Don’t leave unfinished work with Claude Code — offload it to git diff, a TODO file, or a work log.
This approach is a poor fit for always-on setups like Wiring up Claude Code and Codex in tmux to build a game overnight (practice), but given the current issue shape, trusting long-lived sessions too much is the riskier move.

On the prompt side: keep the pre-tool explanation short, don’t pack multiple tool calls into one message, and split the operations you want to run into smaller pieces.
This isn’t a real fix, but in the issues, many reports fired on “long sessions,” “heavy editing,” and “tool calls in rapid succession.”
#63800 also reports that after about 2 hours of use it froze before a tool call and reproduced after a message ending in let me ....
It’s not the same court signature, but the form of stalling right before moving to a tool call in a long conversation is shared.

I looked at Claude Code’s internal implementation and the Bun runtime before in Claude Code’s full source exposed and OpenAI Codex’s token-theft vulnerability surfaced around the same time.
This court isn’t a source leak or a local-tool vulnerability — it breaks at the boundary between model output and the harness.
The moment raw <invoke> shows on screen, attaching the session JSONL and the issue number and running /bug is more useful as information than chasing tool-side logs.

References