-
-
Notifications
You must be signed in to change notification settings - Fork 93
Description
Description
After installing DCP, I'm frequently getting this error from the Anthropic API:
"This model does not support assistant message prefill. The conversation must end with a user message."
The error requires manually resuming the session each time. It started happening significantly more often after installing DCP and correlates with DCP's message manipulation.
Root Cause Analysis
The following analysis was performed by Claude Opus 4.6 by inspecting DCP's distributed source code.
filterCompressedRanges() in prune.js rebuilds the message array by dropping pruned messages and injecting synthetic user summaries at anchor points. However, there is no validation that the resulting array ends with a user or tool message.
If a compression block covers the tail of the conversation — or if the last surviving message after pruning happens to be an assistant message — the array is sent to the Anthropic API as-is, which rejects it because it ends with an assistant message.
This is not caught anywhere in the 16-step pipeline in createChatMessageTransformHandler (hooks.js). There is no post-pipeline tail-role assertion.
Secondary risk areas:
applyPendingManualTrigger()silently does nothing if it can't find a user message to replaceinjectCompressNudges()happily injects into a trailing assistant message rather than flagging the structural problem
Steps to Reproduce
- Install DCP with default or custom config
- Use
anthropic/claude-opus-4-6(or any Anthropic model) - Run a long session where DCP compresses content near the tail of the conversation
- Observe the prefill error when the next LLM request fires
The error is intermittent and depends on which messages get pruned and where the compression anchor lands relative to the conversation tail.
Suggested Fix
Add a tail-role guard at the end of createChatMessageTransformHandler in hooks.js, after all pipeline steps complete (after line ~64, before logger.saveContext()):
// Ensure the message array doesn't end with an assistant message
if (output.messages.length > 0) {
const lastMsg = output.messages[output.messages.length - 1];
if (lastMsg.info.role === "assistant") {
// Append a synthetic user message to satisfy API requirements
output.messages.push(createSyntheticUserMessage(/* ... */));
}
}The createSyntheticUserMessage helper already exists in messages/utils.js and could be reused here.
Environment
- OpenCode: latest
- DCP:
@tarquinen/opencode-dcp@latest(3.1.5) - Model:
anthropic/claude-opus-4-6 - OS: macOS