[BUG] VS Code: prompt history drops slash-command arguments

Status Open
Reported on v2.1.294
Maintainer reply None cached
Activity 0 comments · opened Oct 8, 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?

Bug Description
In the VS Code extension chat, a prompt made of a slash command / skill plus arguments
is recalled from history without its arguments. Stopping the next run then restores
the old arguments without the command.

Evidence
Step 1 reached the skill with ARGUMENTS: some args; the prompt recalled in step 2
reached it with no arguments. Sending works; the history entry and the interrupt
restore are wrong. No cancel is needed for step 2.

Environment

  • VS Code: 1.135.0
  • Claude Code extension: 2.1.294 (darwin-arm64)
  • OS: macOS 14.8.2
  • Terminal CLI: not tested
  • Reproduces with no UserPromptSubmit hooks active (the only plugin with one was disabled, window reloaded)
  • The session transcript stores the original prompt with its <command-args>, so the

arguments are lost in the input box's ↑ history, not in the saved session

Related: #54610

What Should Happen?

Expected behavior

  • ↑ recalls a prompt exactly as it was sent, command and arguments together

(/my-skill some args). Sending it again runs the skill with the same arguments.

  • After Stop, the input box holds the prompt that was interrupted, exactly as sent

(/my-skill in step 3). It never holds text from an earlier prompt.

  • Slash-command prompts behave like plain-text prompts, which are already recalled and

restored in full.

Error Messages/Logs

Steps to Reproduce

  1. Send /my-skill some args (reproduced with a project skill). Let the run finish.
  2. Press ↑ in the empty input.
  • Expected: /my-skill some args
  • Actual: /my-skill (arguments gone). Sending it runs the skill with no arguments.
  1. Send that recalled /my-skill and click Stop while it runs.
  • Expected: the input box is restored with /my-skill (the interrupted prompt)
  • Actual: the input box is restored with some args: the arguments from step 1,

without the command.

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.197 (Claude Code)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

Where it likely breaks
Read from the shipped 2.1.294 webview/index.js. Minified names are from that build;
search for the quoted property names instead.

  1. ↑ history is rebuilt from session messages, not from what was typed.

The input hook that returns { cycleMessage, resetHistory } builds its list from
messages (+ heldPrompts): non-synthetic user messages with no parent tool use, each
text block run through the user-message content parser and joined.
(2.1.294: nx() / qD0().)

  1. The tag parser is fine. The function that turns <command-name> / <command-args>

into { name, args, line } (2.1.294: ev1() via rk0()) returns /my-skill some args
for the line stored in the session transcript. Checked by running the bundle's own
function on the stored entry.

  1. The local message is overwritten when the CLI echoes the prompt back. send()

pushes a local user message with the typed text and, for slash commands, adds its uuid
to slashSendUuids. When the echo arrives (isReplay: true, same uuid), the merge
function (2.1.294: gv1()) replaces that message's last text block with only the
last text block of the echoed content (content.findLast(b => b.type === "text")).
If the echo for a slash command spreads the tags over several text blocks, or has no
<command-args>, the arguments are lost from the in-memory message, and ↑ shows
/my-skill. Not confirmed: the echoed stream-json message was not captured.

  1. Stop restore: not located. It returns the previous send's arguments without the

command, which suggests it reads the same command/argument split from a stale source.

Suggested fix

  • When send() creates the local message, store the exact submitted text on it (e.g. a

submittedText field). Have the replay merge keep that field, and have the ↑ history
builder and the Stop restore use it first. History then no longer depends on the
format of the echo.

  • Minimum fix: in the replay merge, keep the local text for uuids in slashSendUuids, or

parse the whole echoed content (all text blocks joined) instead of only the last block.

  • Regression test: send /skill a b, deliver an isReplay echo in the slash-command tag

format, and assert that ↑ returns /skill a b. Then interrupt and assert the input is
restored to /skill a b.

View original on GitHub ↗