Skip to content

[BUG]: Tab agent switch: first message after the switch still runs on the previous agent's system prompt #41387

Description

@mewmewmemw

Description

On v1.18.15, switching between custom primary agents with Tab in a live session records the new agent correctly, but the first user turn after the switch still runs on the previous agent's system prompt.

Expected: The first message after a Tab switch uses the new agent's system prompt.

Actual: The first user turn after the switch runs on the previous agent's system prompt. The model self-identifies as the previous agent and follows its prompt rules, while the message metadata (data.agent/data.mode) and the server log (message=stream agent=<new agent>) both record the new agent. The turn after that (next user message, no switching at all) picks up the correct agent's prompt.

Evidence — observed twice out of 11 switches, in both directions, across two agent pairs:

  • In its reasoning, the model quotes the previous agent's system prompt verbatim. In one case it quoted a revision of our prompt that no longer existed in opencode.json at that time (verified against git history and backups), and the conversation history contains no prompt text at all — so the text could only come from the request's system prompt.
  • Always exactly the first user turn after the switch.
  • No errors or warnings in the server log around the event.

Related: #8946 (stale agent state when returning to a session). Suspected spot: agent resolution in createUserMessage (packages/opencode/src/session/prompt.ts) — the first processing loop after the switch may use the pre-switch agent state; the system prompt itself is built per call from agent.info.system (packages/core/src/session/runner/llm.ts).

Side note: nothing in the stored data records which agent's system prompt was actually sent (step-start carries no agent snapshot), so this class of bug is invisible without reasoning traces — worth logging at generation time.

Plugins

none

OpenCode version

1.18.15

Steps to reproduce

  1. Define two custom primary agents (mode: "primary") in opencode.json with distinctly different system prompts; include a self-identification line in each prompt (e.g. "you are agent , announce it in your first reply") so the active prompt is observable.
  2. Start a session with agent A and converse for a few turns.
  3. Press Tab to switch to agent B and send a message.
  4. Occasionally (2 of 11 in our setup): the reply follows agent A's prompt (self-identifies as A) while the message metadata says agent=B.
  5. Send one more message — agent B's prompt is picked up starting from the next turn.

Screenshot and/or share link

Session DB extracts (message metadata + reasoning quotes for both incidents) available on request; can provide a /share link of an affected session.

Operating System

macOS 15.6

Terminal

kitty

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions