Skip to content

Fix OpenCode plugin Jinja template corruption with Qwen3.6#1114

Open
atomicflag wants to merge 1 commit into
backnotprop:mainfrom
atomicflag:fix-system-transform-granular
Open

Fix OpenCode plugin Jinja template corruption with Qwen3.6#1114
atomicflag wants to merge 1 commit into
backnotprop:mainfrom
atomicflag:fix-system-transform-granular

Conversation

@atomicflag

Copy link
Copy Markdown

Issue

The OpenCode plugin's system.transform hook was corrupting OpenCode's Jinja template when injecting planning prompts. The error appeared as:

raise_exception('System message must be at the beginning.')

This occurred when using Qwen3.6 models with their chat template.

Root Cause

The plugin was pushing planning prompts and improvement context as separate elements in the output.system array:

output.system.push(getPlanningPrompt());
output.system.push(improveContext);

OpenCode maps each element of output.system to a separate system message. The Qwen3.6 Jinja template only allows one system message at position 0:

{%- for message in messages %}
    {%- if message.role == "system" %}
        {%- if not loop.first %}
            {{- raise_exception('System message must be at the beginning.') }}
        {%- endif %}
    {%- endif %}
{%- endfor %}

When the plugin pushed multiple elements, OpenCode created multiple system messages, causing the template to fail at position > 0.

Jinja template reference: https://huggingface.co/Qwen/Qwen3.6-35B-A3B-FP8/raw/main/chat_template.jinja

Solution

Instead of pushing new elements to output.system, the plugin now appends content to the first element (output.system[0]):

output.system[0] += "\n\n" + getPlanningPrompt();

This preserves the multi-message output.system array structure while keeping all injected content within the original system message (element 0). The Jinja template sees only one system message at position 0, containing all the plugin's additions.

Testing

  • Verified the fix works with Qwen3.6 models
  • All existing tests pass (10/10 in plan-mode.test.ts)
  • No breaking changes to other agents or models

…lement

The plugin previously pushes planning prompts and improvement contexts as
separate elements in the output.system array. This change appends them to
output.system[0] with newline separators instead. This keeps all system
instructions within a single message block to prevent potential parsing or
formatting issues when the agent processes the context.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant