anthropics / anthropics/claude-code
[BUG] Side chat on a third-party model gateway: an undeclared tool call leaks as raw DSML text and can hang the panel
- Dominant language
- Python
- Stars
- 145k
- Forks
- 23.1k
- PR merge metrics
- PR metrics pending
Description
### Environment
- Claude Desktop 1.52386.6.0 (Windows 11, build 26200), Code tab, local session
- Model backend: third-party gateway via developer mode / 3P (model name `claude-sonnet-5` mapped to a specific third-party backend, Anthropic-compatible endpoint)
- Bundled CLI engine 2.1.270
### What happens
Opening the side chat (Ctrl+;) on a Code session and asking something that invites "checking" (e.g. "check the log", "what's the progress") can produce a reply in which the tool call is emitted as **raw markup text** instead of a structured tool call:
```
<||DSML|| calls>
<||DSML|| invoke name="Bash">
<||DSML|| parameter name="command" ...>ls -la ...; cat ...
```
Nothing executes, the markup is rendered verbatim in the panel, and the turn effectively stalls. It is intermittent — fails more often than it succeeds.
### Diagnosis (from the app bundle + controlled requests)
- In this version the side chat's allowed tools are a read-only trio: `Read`, `Grep`, `Glob` — no `Bash` (the system-prompt append explicitly says "You CANNOT … run commands").
- Every leaked call observed was an attempt at an **undeclared** tool (`Bash`) that the model imitates from the session history (the history is full of shell usage).
- With this backend family, when the model goes for an undeclared tool, the call collapses into DSML text markup — a widely reported failure mode for it (e.g. vllm-project/vllm#51914: "intermittently emits malformed DSML tool-call start wrapper") — and the client has no fallback parser, so it renders raw text and the turn stalls.
- Controls: declared-tool calls work fine on the same gateway (3/3 clean, both OpenAI- and Anthropic-format probes). Clean short-context requests never leak; this only reproduces under real side-chat conditions (long shell-flavored history, inherited max effort, preset prompt).
### Relation to existing reports
#91975 and #92651 describe the same visible symptom ("side chat hangs / stops responding after the first reply", "intermittent, fails more often than it succeeds") without identifying this layer. This report adds the root cause: **undeclared-tool attempt → DSML text leak → no execution → stalled panel**. Likely the same underlying issue; worth cross-linking.
### Suggested hardening (client side)
1. Tolerate/sanitize `DSML`-family markup when it arrives as text from third-party backends; and/or
2. Detect attempts at tools that were not offered and return a corrective note to the model instead of stalling the turn.
### Repro
1. Claude Desktop (Code tab), third-party gateway (Anthropic-compatible endpoint serving the same backend model).
2. In a session whose recent history includes shell commands, open the side chat and ask something like "check the log / what's the progress".
3. Observe the raw `<||DSML|| …>` text and the stalled turn. — Instructing the side chat to "just answer, don't run anything" produces a clean reply, confirming the leak is tied to off-protocol tool attempts.
🤖 Drafted and filed by Claude (Claude Code) at the user's request.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reproducing the side-chat behavior in the Code tab with a shell-heavy session and a third-party gateway, then trace the app-bundle path that handles tool-call responses and renders panel text. Done means undeclared-tool or DSML-formatted responses no longer render raw markup or leave the turn stalled; no specific source file or test is named in the report.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100