Description
Bug description
When using a custom openai compat server, opencode fails during streaming response parsing if the model server returns an empty string for choices[0].delta.role.
It looks like opencode strictly validates the streaming chunk and requires:
But some providers/model servers return:
This causes a AI_TypeValidationError / ZodError, and the stream processing fails.
Actual behavior
opencode throws a validation error like:
AI_TypeValidationError: Type validation failed
Invalid input: expected "assistant"
path: choices[0].delta.role
Relevant log excerpt:
ERROR service=llm providerID=corenet modelID=zhipu/glm-5 ... error={"error":{"name":"AI_TypeValidationError","cause":{"name":"ZodError","message":"[
{
"code": "invalid_union",
"errors": [
[
{
"code": "invalid_value",
"values": [
"assistant"
],
"path": [
"choices",
0,
"delta",
"role"
],
"message": "Invalid input: expected \"assistant\""
}
],
[
{
"expected": "object",
"code": "invalid_type",
"path": [
"error"
],
"message": "Invalid input: expected object, received undefined"
}
]
],
"path": [],
"message": "Invalid input"
}
]"},"value":{"choices":[{"index":0,"delta":{"role":"","content":"**","reasoning_content":""}}],"created":1779246053,"id":"270bc6e14cb74c75a0f10e2d23e03680","model":"glm-5","object":"chat.completion.chunk","usage":{"prompt_tokens":0,"completion_tokens":0,"total_tokens":0,"prompt_tokens_details":{}}}}} stream error
Another example chunk from the same stream:
{
"choices": [
{
"index": 0,
"delta": {
"role": "",
"content": "Local",
"reasoning_content": ""
}
}
],
"created": 1779246053,
"id": "270bc6e14cb74c75a0f10e2d23e03680",
"model": "glm-5",
"object": "chat.completion.chunk",
"usage": {
"prompt_tokens": 0,
"completion_tokens": 0,
"total_tokens": 0,
"prompt_tokens_details": {}
}
}
Expected behavior
opencode should tolerate providers that return an empty or missing delta.role in streaming chunks.
Possible ways to handle this:
- treat empty
role as "assistant" for assistant message streams, or
- allow
role to be empty/missing on subsequent chunks, or
- normalize provider responses before Zod validation
Why this seems to be an opencode compatibility issue
Some model servers do not strictly follow the expected streaming schema and may emit role: "" instead of "assistant".
Even if the upstream provider behavior is imperfect, opencode could be more robust here, since the rest of the chunk is valid and usable.
Plugins
No response
OpenCode version
1.15.5
Steps to reproduce
A provider-specific setup is not required. This can be reproduced with any mock or proxy that returns OpenAI-compatible streaming chunks with an empty delta.role.
Minimal reproduction idea
Configure opencode against a local/mock OpenAI-compatible endpoint and return a streaming SSE response containing a chunk like:
{
"choices": [
{
"index": 0,
"delta": {
"role": "",
"content": "hello"
}
}
],
"created": 1779246053,
"id": "example_chunk_id",
"model": "test-model",
"object": "chat.completion.chunk"
}
Then observe that opencode fails with a type validation error.
Reproduction outline
- Run any local mock server that exposes an OpenAI-compatible chat/completions streaming endpoint
- Configure opencode to use that endpoint
- Start a streamed chat request
- Have the mock server emit an SSE chunk where:
"choices": [
{
"delta": {
"role": "",
"content": "hello"
}
}
]
- Observe stream failure with
AI_TypeValidationError
Screenshot and/or share link
No response
Operating System
Windows 11
Terminal
nushell
Description
Bug description
When using a custom openai compat server, opencode fails during streaming response parsing if the model server returns an empty string for
choices[0].delta.role.It looks like opencode strictly validates the streaming chunk and requires:
But some providers/model servers return:
This causes a
AI_TypeValidationError/ZodError, and the stream processing fails.Actual behavior
opencode throws a validation error like:
Relevant log excerpt:
Another example chunk from the same stream:
{ "choices": [ { "index": 0, "delta": { "role": "", "content": "Local", "reasoning_content": "" } } ], "created": 1779246053, "id": "270bc6e14cb74c75a0f10e2d23e03680", "model": "glm-5", "object": "chat.completion.chunk", "usage": { "prompt_tokens": 0, "completion_tokens": 0, "total_tokens": 0, "prompt_tokens_details": {} } }Expected behavior
opencode should tolerate providers that return an empty or missing
delta.rolein streaming chunks.Possible ways to handle this:
roleas"assistant"for assistant message streams, orroleto be empty/missing on subsequent chunks, orWhy this seems to be an opencode compatibility issue
Some model servers do not strictly follow the expected streaming schema and may emit
role: ""instead of"assistant".Even if the upstream provider behavior is imperfect, opencode could be more robust here, since the rest of the chunk is valid and usable.
Plugins
No response
OpenCode version
1.15.5
Steps to reproduce
A provider-specific setup is not required. This can be reproduced with any mock or proxy that returns OpenAI-compatible streaming chunks with an empty
delta.role.Minimal reproduction idea
Configure opencode against a local/mock OpenAI-compatible endpoint and return a streaming SSE response containing a chunk like:
{ "choices": [ { "index": 0, "delta": { "role": "", "content": "hello" } } ], "created": 1779246053, "id": "example_chunk_id", "model": "test-model", "object": "chat.completion.chunk" }Then observe that opencode fails with a type validation error.
Reproduction outline
AI_TypeValidationErrorScreenshot and/or share link
No response
Operating System
Windows 11
Terminal
nushell