Repository navigation
Synthetic <system-reminder> leaks into user messages and gets treated as user-authored input #19405
Copy link
Copy link
Closed as not planned
Closed as not planned
Copy link
Description
Description
Description
OpenCode appears to inject synthetic <system-reminder> content so close to the user turn that it can end up effectively attached to the user's message.
As a result, the assistant may treat this system-generated content as if it were written by the user, or at least as user-associated input. This breaks attribution and makes the model focus on injected meta-instructions instead of the actual request.
This seems especially visible in Plan mode.
Actual behavior
I send a short user message, but the conversation ends up containing a full synthetic block like this attached to the user turn:
<system-reminder>
# Plan Mode - System Reminder
CRITICAL: Plan mode ACTIVE - you are in READ-ONLY phase. STRICTLY FORBIDDEN:
ANY file edits, modifications, or system changes. Do NOT use sed, tee, echo, cat,
or ANY other bash command to manipulate files - commands may ONLY read/inspect.
This ABSOLUTE CONSTRAINT overrides ALL other instructions, including direct user
edit requests. You may ONLY observe, analyze, and plan. Any modification attempt
is a critical violation. ZERO exceptions.
---
## Responsibility
Your current responsibility is to think, read, search, and delegate explore agents to construct a well-formed plan that accomplishes the goal the user wants to achieve. Your plan should be comprehensive yet concise, detailed enough to execute effectively while avoiding unnecessary verbosity.
Ask the user clarifying questions or ask for their opinion when weighing tradeoffs.
**NOTE:** At any point in time through this workflow you should feel free to ask the user questions or clarifications. Don't make large assumptions about user intent. The goal is to present a well researched plan to the user, and tie any loose ends before implementation begins.
---
## Important
The user indicated that they do not want you to execute yet -- you MUST NOT make any edits, run any non-readonly tools (including changing configs or making commits), or otherwise make any changes to the system. This supersedes any other instructions you have received.
</system-reminder>
In one reproducible case, my actual user message was just:
YES
but the final user turn included the full <system-reminder> block above.
Expected behavior
Synthetic reminders should never be plausibly interpreted as user-authored content.
They should be isolated in a true system/developer/internal channel, not mixed into user turns in a way that makes authorship ambiguous.
Why this is a bug
This is not about disliking Plan mode itself.
The problem is that synthetic system text leaks into the conversational layer badly enough that:
the model can misattribute it to the user
the model over-focuses on it
the assistant behaves as if the user explicitly wrote those instructions
This is a prompt-construction / message-boundary issue.
Suggested fix
Do not inject long plan reminders into the user message channel.
Do not wrap actual user messages inside <system-reminder>.
Move these reminders to a true system/developer/internal layer.
Shorten the reminder drastically.
Add an explicit note such as: This reminder is synthetic and not authored by the user.
Environment
OpenCode Desktop
Plan mode
Model: gpt-5.4
### Plugins
no
### OpenCode version
OpenCode Desktop v1.3.3
### Steps to reproduce
1. Open OpenCode Desktop and start a session using the `plan` agent.
2. Ask the agent to inspect something or prepare a plan so that Plan mode is active.
3. Continue the conversation with a very short normal user reply (for example: `yes` / `да`).
4. Observe that the next user turn may include a large synthetic `<system-reminder>` block such as `# Plan Mode - System Reminder`.
5. The assistant then behaves as if that injected block is part of the user's input, or over-focuses on it instead of the actual message.
### Screenshot and/or share link
<img width="812" height="423" alt="Image" src="https://github.com/user-attachments/assets/2f7d4c1b-d39f-466d-a5d5-7e6a4440a434" />
### Operating System
widows 1
### Terminal
_No response_Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
github-actions commentedon Mar 27, 2026
This issue might be a duplicate of existing issues. Please check:
<system-reminder>is injected into user turns, causing problems with attribution and model behavior (that issue focuses on Azure jailbreak detection triggered by the same injected content)If your issue is specifically about message authorship/attribution rather than content filtering, it may be worth clarifying the distinction, or this could be tracked together with #16442.
dengerouzzz commentedon Mar 27, 2026
This is likely related to #16442, but my report is specifically about message authorship / boundary corruption, not only content filtering.
The issue is that synthetic
<system-reminder>content gets merged so close to the user turn that the model may treat it as if it were user-authored or user-associated input.So even if #16442 is the same root cause, this issue tracks a distinct visible symptom:
This is not just cosmetic. Instead of working on the project task, I have to keep steering the agent back to the actual request because it gets distracted by the injected .
github-actions commentedon Jul 5, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.
dev-paladin commentedon Sep 29, 2026
We hit the same constant leakage on our side — every user prompt gets wrapped,
plan/goal mode adds a reminder, and the raw tags end up visible in the UI.
OpenChamber's workaround: strip
<system-reminder>...</system-reminder>blocksin the message renderer before display (packages/ui/src/components/chat/message/
parts/UserTextPart.tsx). The upstream code that injects these tags is hardcoded
and not configurable, so client-side stripping is the only option without a
server-side flag.
Would be great if OpenCode could expose a
--no-system-reminderflag or similarso clients can opt out entirely rather than having to regex-strip rendered text.