Hacktoberfest 2026:維護者為十月標記出來的 issue,仍然開放、適合新手。 瀏覽 Hacktoberfest issue

Multiple-choice ask_user silently renders as a free-text prompt when trailing tool-call parameters leak into the preceding string argument

未關閉
#4,817 0 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

評估

難度
4/5
預估耗時
3-5 天
新手友好度
45/100
Issue 類型
缺陷
描述清晰度
基本清楚
活躍度
活躍
技術堆疊
shell
領域
cli, tooling

研究方向

首先追蹤產生原始 tool.execution_start 事件的參數解析器,並使用格式錯誤的 question 與 -B 範例作為重現輸入。檢查解碼後的字串值中的尾隨參數標記是如何處理的。完成標準是:格式錯誤的部分解析不再在捨棄參數的情況下靜默執行,且解析器涵蓋了回報的這些形式。

由索引模型根據 Issue 內容生成。

描述

triage
Describe the bug

An ask_user call that supplies choices sometimes renders as a plain free-text prompt ("Type your answer…") instead of the usual clickable option buttons — and the options themselves show up as a literal JSON array printed at the end of the question text.

The cause is upstream of any UI: the assistant emits Anthropic-style <parameter name="…"> markup inside a string argument, and the argument parser recovers only the first parameter. Every trailing parameter is silently absorbed into that first parameter's string value. Unlike #3765 (where the whole <invoke> block leaks as text and the tool never runs), here the tool call does execute — just with silently truncated arguments, so nothing surfaces as an error.

Verbatim from the session transcript (tool.execution_start), reformatted only for line breaks:

{
  "toolName": "ask_user",
  "arguments": {
    "question": "…Tests 244 → 247 passing, typecheck clean. Commit it?</question>\n<parameter name=\"choices\">[\"Commit (Recommended)\", \"Edit message\", \"Skip repo\", \"Cancel\"]"
  }
}

arguments has exactly one key. choices never arrives, so the client correctly renders a free-text prompt — it has no options to draw.

It is not ask_user-specific. The same shape corrupts ordinary tools, where the damage is worse because the call runs with wrong arguments and nobody notices. A grep call that lost its -n:

{ "-B": "30\">\n<parameter name=\"-n\">true", "output_mode": "content", "pattern": "latched" }
Affected version

Engine 1.0.84-4 (running inside the GitHub Copilot desktop app). Standalone CLI on PATH is 1.0.81-12. Occurrences in my logs span 2026-08-18 → 2026-09-11, so this is not new to one release.

Steps to reproduce the behavior

Not deterministic on demand — it depends on model output. What reliably produces it:

  1. Run a long session on claude-opus-5.
  2. Have the agent call ask_user with a choices array and a long question (every affected call was 643–944 characters; nothing shorter ever broke).
  3. Once one malformed call lands, every subsequent tool call of that kind in the session is malformed too — the model copies its own bad output from the transcript.
  4. Run /compact. The bad exemplar leaves the context window and calls go back to normal.

Step 3–4 is the strongest signal and is fully reproducible from logs — see the investigation block.

Expected behavior

Either the model never emits parameter markup inside a string value, or — more robustly — the argument parser refuses to accept a partial parse. A string value containing </param> / <parameter name="…"> is unambiguously a serialization failure, and the trailing parameters are trivially recoverable from it. Today it silently succeeds with dropped arguments, which is the worst of the three options.

Additional context

Suggested labels (I can't set them): area:tools, type: Bug.

Related: #3765 — same root family (parameter markup leaking), different failure mode: there the call is never executed; here it executes with silently truncated arguments.

Environment
Engine version   1.0.84-4  (GitHub Copilot desktop app)
CLI on PATH      1.0.81-12
OS               Microsoft Windows NT 10.0.26200.0
CPU arch         AMD64
Shell            PowerShell 7
Surface          desktop app, project session
Model            claude-opus-5 (long-context tier)
Frequency

Measured, not estimated — scanned every tool.execution_start event in my local session store:

Metric Value
Tool calls scanned 145,260
Calls with leaked parameter markup 18 (0.012%)
On claude-opus-5 17
On all other models combined 1 (claude-opus-4.8)

Tools affected: ask_user ×12, grep ×2, an ADO MCP tool ×2, a Bluebird MCP tool ×1, create ×1.

The global rate is low but misleading — it is heavily clustered. Within an affected session the rate is effectively 100% until a compaction clears it.

Extensions

Not tried with extensions disabled. Canvas extensions were loaded, but they cannot plausibly be involved: the corruption is present in the raw tool.execution_start event, before any client renders it.

Diagnostics available on request
  • Redacted events.jsonl excerpts for both affected sessions
  • The scan script used to produce the frequency table
In-depth investigation

The corruption is already present in the raw event, before anything renders it. The tool.execution_start record in the local session store shows arguments carrying a single question key. No client can draw option buttons from that — there are no options in the payload. So this is not a UI bug, and it will reproduce on any surface.

Why it's easy to miss. The stray </question> and <parameter name="choices"> don't show up on screen — only the bare ["Commit (Recommended)", …] array does. That makes it read as a formatting quirk rather than a dropped argument, which is why it took a log scan to find.

Contagion, bounded by compaction. This is the part I'd most like a maintainer to look at, because it turns a rare glitch into a session-wide outage.

Session A — 30 ask_user calls, all claude-opus-5:

calls  1–6    ok
               ← 5 compactions in 31 minutes (heavy context pressure)
calls  7–11   MALFORMED   (contiguous, ~26 h, no compaction in between)
               ← compaction
calls 12–30   ok          (19 consecutive clean calls)

The malformed run is bounded exactly by compaction events on both sides.

Session B — 7 ask_user calls, claude-opus-5, zero compactions for the life of the session (74% of a 1M context window): 7 of 7 malformed, starting with the very first one.

Reading: once one malformed call is in the context window it acts as a few-shot exemplar and the model reproduces its own broken shape indefinitely. Compaction rewrites the context, the exemplar disappears, and output returns to normal. Two sessions is a small sample, so I'd call this a strong inference rather than proven — but it matches both cases exactly and gives users a workaround (/compact, or switch model).

The existing guard isn't holding. The harness system prompt already carries a mitigation for this class — "when calling a tool whose parameter is an object, emit a real JSON object for that parameter. Never put XML or angle-bracket markup inside string values of a tool call." That instruction was in context for every one of the 18 malformed calls. A prompt-level guard can't win against the model's own prior output sitting in the same window; this needs a parser-level check.

Suggested fix, in priority order:

  1. Reject partial parses. If a decoded string argument contains </…> or <parameter name=, treat the tool call as malformed rather than passing along truncated arguments. Silent success is the real defect here.
  2. Recover them. </question>\n<parameter name="choices">["a","b"] is unambiguously parseable back into the intended arguments. A tolerant post-parse pass would fix the user-visible symptom outright.
  3. Break the contagion. If a malformed call is detected, avoid replaying its raw text into subsequent context — otherwise one bad call poisons the rest of the session.
主要語言
Shell
星號
11.2k
分支
1.9k
平均合併
14 小時 16 分鐘
30 天內合併 PR
6

貢獻指南

開啟貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

github/copilot-cli 的其他 Issue

查看 github/copilot-cli 的全部 Issue

相似的 Issue

更多 Shell/Bash Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。