Skip to content

Step-cap assistant message causes 400 on Claude models with thinking enabled #32548

Closed as not planned

Description

@kevinfaveri

Description

When an agent hits its step cap, the prompt loop appends an assistant-role message containing the "MAXIMUM STEPS REACHED" text. This makes the final message in the request an assistant turn, which Anthropic treats as a response prefill. Claude models with thinking enabled reject it:

400 This model does not support assistant message prefill. The conversation must end with a user message.

The injection is at packages/opencode/src/session/prompt.ts, around line 1343.

Ref: https://docs.claude.com/en/docs/build-with-claude/extended-thinking (Feature compatibility): "You can't pre-fill responses when thinking is enabled."

Plugins

opencode-fusion (https://github.com/kevinfaveri/opencode-fusion)

OpenCode version

1.17.7

Steps to reproduce

This is 100% reproducible.

  1. In opencode.json, set a low step cap on any agent:
    {
      "agent": {
        "build": {
          "steps": 2
        }
      }
    }
  2. Start a session using a Claude model with thinking enabled (Opus 4.6+)
  3. Give it a task that requires tool calls, e.g. "read package.json, then search in the web multiple times for the dependencies if we can trust them and summarize it"
  4. The agent hits the cap after 2 steps, OpenCode appends the MAXIMUM STEPS REACHED assistant message, and the next request returns:
    400 This model does not support assistant message prefill. The conversation must end with a user message.

Screenshot and/or share link

Offending code: https://github.com/anomalyco/opencode/blob/dev/packages/opencode/src/session/prompt.ts#L1343

Screenshot following repro steps above:

Image

Opencode Export

Session ID: ses_12fe4e903ffeyCq14Em7Xyshcb
Created: 6/16/2026, 8:04:56 PM

User:
read package.json search every dependency online and summarize it

Assistant (Build, Claude Opus 4.6, 5.8s):

Thinking: The user wants me to read the package.json file in the current project directory and then research each dependency online to summarize what each one does. Let me start by reading the package.json file.

Tool: memorysearch
Input: { "query": "package.json dependencies project stack", "collection": "all" }
Output: Searched in opencode_memory and opencode_plans, 61 + 3 hits.

Tool: read
Input: { "filePath": "/Users/kevinfaveri/Projects/KevinProfile/package.json" }
Output: package.json with 14 dependencies and 8 devDependencies (Next.js 16.2.6, React 19.2.4, AI SDK, Tailwind v4, etc.)

Assistant (Build, Claude Opus 4.6, 0.6s):

400 This model does not support assistant message prefill. The conversation must end with a user message.

Operating System

macOS 26.5.1

Terminal

Ghostty

Activity

  1. github-actions commented on Jun 16, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    Please review those issues to see if your report is already tracked there before continuing separately.

  2. kevinfaveri commented on Jun 16, 2026

    @kevinfaveri
    Author

    The way I'm working around this at the fusion tool and locally is by setting a max steps per agent (built in and the ones from plugin) to a virtually very high number so its never hit, lol. Seems to address most of my frustrations @nexxeln

    However having to use all those deep configs can be very non user friendly hence the issue and PR @nexxeln

  3. Anooshiravan commented on Jun 28, 2026

    @Anooshiravan

    Hit the same root cause from a different angle. Our setup uses Qwen3.6-35B-A3B via LiteLLM, no Claude/thinking involved — but the trailing assistant prefill still kills the response. The model just echoes the prefill verbatim (one stop token, completion_tokens=1) and the user sees the "CRITICAL - MAXIMUM STEPS REACHED..." block as if it came from the model. Confirmed end-to-end by replaying the captured request directly against the LLM:

    • role: assistant → 1 completion token (echo), useless
    • role: user → 270 tokens, clean summary, finish_reason: stop

    So the issue isn't specific to Claude/thinking — that's just the loudest symptom. Any provider that honors the assistant prefill convention has the same broken UX.

    Opened #34276 with a two-line fix: change assistant to user in both prompt loops (V1 prompt.ts, V2 runner/llm.ts). Same approach as the earlier #16883, which was auto-closed by the template bot in March.

    #32546 takes a different route (config flag to suppress the cap message). That works as an escape hatch, but the message itself is useful — the model genuinely should know it hit the cap so it can summarize instead of being silently truncated. The role fix preserves the message and makes the model actually respond to it.

  4. fernanDOTdo commented on Jul 18, 2026

    @fernanDOTdo

    Still reproduces on 1.18.3, and the injection line is unchanged on dev. Hit it twice, each at exactly the agent's configured step ceiling, with all prior steps succeeding:

    • claude-sonnet-5 subagent, steps: 40, thinking variant (max) → 400 on step 40
    • claude-opus-4-8 subagent, steps: 200, thinking variant (xhigh) → 400 on step 200

    #34276 (send as user role instead of assistant prefill) is the right fix — the wrap-up message is useful, the model just needs to be allowed to answer it.

  5. AdelinoGP commented on Aug 8, 2026

    @AdelinoGP

    Is this still not fixed? Even on V2 I am still getting this issue, I think #24505 might be a good way of fixing it, maybe as an option at least

  6. github-actions commented on Oct 8, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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