Skip to content

About

OpenCode plugin: prevent 'assistant message must not be empty' API errors (workaround until anomalyco/opencode#45839 lands)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

opencode-fix-empty-assistant-messages

An OpenCode plugin that prevents sessions from dying with:

litellm.BadRequestError: OpenAIException - the message at position N with role 'assistant' must not be empty

Once this error appears, every subsequent request in the session fails the same way and the session can no longer continue. This plugin sanitizes the message history right before it is sent to the model, so the error never happens.

Upstream fix pending: a proper fix has been submitted to OpenCode core as anomalyco/opencode#45839. Once that PR is merged and released, you can simply remove this plugin.

Root cause

OpenCode replays each stored assistant message as one API message per step (split at step-start parts). A step that contains only reasoning output — which OpenAI-compatible providers drop — or an empty text chunk serializes to an assistant message with empty content, which litellm/OpenAI-compatible gateways reject. This happens in the wild when:

  • a turn is aborted mid-generation (the partial message is kept in history, including its reasoning-only steps), or
  • a model/provider streams empty text chunks (observed with reasoning models behind OpenAI-compatible proxies such as litellm).

What the plugin does

Hooks experimental.chat.messages.transform (runs before history is converted to model messages) and, for every assistant message:

  1. drops empty text parts ("" carries no information anyway);
  2. splits parts at step-start boundaries and drops every step segment that has no tool call and no non-empty text — exactly the segments that would otherwise serialize to an empty assistant message.

Messages containing Anthropic signed thinking blocks are left untouched (OpenCode core already rewrites their empty-text separators to a single space, and separator positions matter for the signature).

Install

No npm account needed — add the GitHub spec to the plugin array in your opencode.json (global ~/.config/opencode/opencode.json or project-level):

{
  "plugin": ["github:impptg/opencode-fix-empty-assistant-messages"]
}

Restart OpenCode. That's it — plugins are loaded at startup.

If the package is published to npm, the shorter "plugin": ["opencode-fix-empty-assistant-messages"] works too. Alternatively, without any package manager: copy index.ts into ~/.config/opencode/plugins/.

Uninstall

Remove the entry from plugin in opencode.json (or delete the file from ~/.config/opencode/plugins/) and restart OpenCode.

If you installed this because of the empty-assistant-message bug: watch anomalyco/opencode#45839. Once the upstream fix lands in a release you use, this plugin is no longer needed.

Already broken sessions

This plugin prevents new requests from failing. If a session is already corrupted and you need to repair its stored history, back up and clean the OpenCode SQLite DB (~/.local/share/opencode/opencode.db): remove empty text parts and reasoning-only step segments, then restart the client. (The author keeps a small repair script alongside their setup; the plugin alone is enough once history is clean.)

License

MIT


opencode-fix-empty-assistant-messages(中文说明)

一个 OpenCode 插件,防止会话因下面的报错而无法继续:

litellm.BadRequestError: OpenAIException - the message at position N with role 'assistant' must not be empty

一旦出现这个错误,该会话之后的每次请求都会同样失败。本插件在消息历史发送给模型之前进行清洗,从源头避免该错误。

上游修复进行中:已向 OpenCode 官方提交根治 PR:anomalyco/opencode#45839。该 PR 合并并发布后,直接卸载本插件即可。

根因

OpenCode 回放历史时,会把每条 assistant 消息按 step(step-start 边界)拆成多条 API 消息。只包含 reasoning 的 step(OpenAI 兼容 provider 会丢弃 reasoning)或空文本块,会被序列化成 content 为空的 assistant 消息,被 litellm / OpenAI 兼容网关拒绝。常见触发场景:

  • 生成中途被中止(不完整消息保留在历史里,其中包含纯 reasoning 的 step);
  • 模型/代理流式吐空文本块(在 litellm 等 OpenAI 兼容代理后的 reasoning 模型上实测出现)。

插件行为

挂载 experimental.chat.messages.transform 钩子,对每条 assistant 消息:

  1. 删除空 text part;
  2. 按 step-start 切段,丢弃既无工具调用又无非空文本的段——这些正是会序列化成空 assistant 消息的段。

包含 Anthropic 签名 thinking 块的消息不做处理(OpenCode 核心已把其空文本分隔符重写为单个空格,分隔符位置影响签名校验)。

安装

无需 npm 账号——在 opencode.json(全局 ~/.config/opencode/opencode.json 或项目级)的 plugin 数组中直接写 GitHub 地址:

{
  "plugin": ["github:impptg/opencode-fix-empty-assistant-messages"]
}

重启 OpenCode 即可(插件在启动时加载)。

如果之后发布到了 npm,也可以写短形式 "plugin": ["opencode-fix-empty-assistant-messages"]。完全不经过包管理器的话:把 index.ts 拷到 ~/.config/opencode/plugins/ 目录下。

卸载

从 opencode.json 的 plugin 数组中移除(或删除 ~/.config/opencode/plugins/ 下的文件),重启 OpenCode。

关注 anomalyco/opencode#45839:官方修复合入并发布后,本插件就可以卸掉了。

License

MIT

About

OpenCode plugin: prevent 'assistant message must not be empty' API errors (workaround until anomalyco/opencode#45839 lands)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages