Repository navigation
ACP: /rename reports success but doesn't rename the session #5115
Description
Describe the bug
In ACP mode (copilot --acp --stdio), /rename <name> reports success but doesn't rename the session. Copilot advertises the command in available_commands_update, and sending it as a session/prompt ends end_turn in about 1 ms, with no model call, with the reply Session renamed to: <name>. But nothing is saved: the session's workspace.yaml keeps its old name and user_named: false, and session/list keeps returning the old title, from the same process and from a new one. /session rename <name> behaves the same.
ACP has no client method to set a session's title (titles are agent-owned and reported with session_info_update), so /rename is the only way for an ACP client to rename a Copilot session.
Affected version
GitHub Copilot CLI 1.0.95
Steps to reproduce the behavior
- Start
copilot --acp --stdioandinitialize. session/newwith acwd, and send one ordinary prompt, so the session is saved and listed (its title is the first message).- Send a
session/promptwith the text/rename My new name. - The reply is
Session renamed to: My new name, withstopReason: end_turn. - Call
session/listwith thatcwd, in the same process or a new one: the session'stitleis still the first message. - Open
~/.copilot/session-state/<id>/workspace.yaml: still the oldname, anduser_named: false. Nosession_info_updateis sent with the new title.
Expected behavior
/rename <name> over ACP renames the session as it does in the interactive CLI: it saves the name (name, user_named: true), session/list returns it, and Copilot sends a session_info_update with the new title, so the client can update its view.
Additional context
- Windows 11, x86_64. Driven from a Node ACP client (
@agentclientprotocol/sdk). - Writing
nameanduser_named: trueintoworkspace.yamlby hand does change the title insession/list, so the listing side works. Only the command doesn't save. - In the 1.0.95 bundle, one session implementation's
renameSession()calls the nativesession.name.set, and another's is an empty stub (async renameSession(t){}, next togetWorkspace(){return null}). The ACP session seems to get the stub. The success message is printed either way. - Related: Support
/renamein VS Code agent sessions, and let the agent invoke it #4244 (/renamein VS Code agent sessions), Manual/renameis overwritten by later auto-generated session name #2622 (a manual name overwritten by an automatic one).
Activity
rishidevcli54-mcp commentedon Oct 11, 2026
impartshadow commentedon Oct 13, 2026
This is a split-implementation bug: two code paths claim to do the same thing, and only one of them actually does it.
The issue body gives the exact mechanism — "one session implementation's
renameSession()calls the nativesession.name.set, and another's is an empty stub (async renameSession(t){}, next togetWorkspace(){return null})." The ACP session object is getting routed to the stub implementation, but the command handler that prints "Session renamed to: " doesn't check the return value or whether the underlying write happened — it just assumes success once the command parses and dispatches. That's whyend_turnfires in ~1ms with no model call: the whole path is non-blocking because nothing is actually persisted.The check that would catch this before it ships: after
renameSession()returns, read backworkspace.yaml(or whatever the session accessor exposes) and assertname === requestedName && user_named === truebefore emitting the success string; if the stub path returns without writing, that assertion fails immediately in CI with a fake/ACP session fixture, instead of silently succeeding. Equivalently, a contract test instantiating both session implementations against the same interface and diffing observable state afterrenameSession()would surface the stub immediately — any implementation that doesn't mutate state it claims to own is the bug, full stop.Open question: I'm inferring the ACP session object literally is the one with the stub
renameSession/getWorkspace() { return null }pair based on the quoted snippet, but I haven't seen which concrete class gets wired to ACP vs. interactive mode — that mapping (likely in the session factory/router) would confirm or kill this hypothesis.Advisory SFA-2026-1F8C7A25AE · Full redacted write-up: https://impartshadow.github.io/echo-site/failure-cases/acp-rename-reports-success-but-doesn-t-rename-the-se-1f8c7a25ae.html
If this diagnosis is useful, react 👍 to this comment; if it is wrong, react 👎 — I use the verdict to choose what I investigate next.