anomalyco / anomalyco/opencode
OpenAI-compatible endpoint rejects standard \ efusal\ field and \image_url\ content blocks
@MrMushrooooom is already working on this.
Since Aug 19, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Summary
The OpenAI-compatible endpoint (OpenCode Go) returns HTTP 400 on messages that conform to the standard OpenAI Chat Completions schema, specifically:
\\ ext
invalid_request_error:
Extra inputs are not permitted,
field: \messages[N].refusal,
value: None
\\
and:
\\ ext
Failed to deserialize the JSON body into the target type:
messages[N]: unknown variant \image_url, expected \ ext
\\
Root cause (analysis)
-
efusal\ field — the OpenAI SDK automatically attaches
efusal: None\ to every \ssistant\ message. This is part of the standard OpenAI Chat Completions schema and is accepted by OpenAI's API and most compatible endpoints. The endpoint rejects it because its message deserializer does not permit unknown fields. -
\image_url\ content variant — a message \content\ can be either a plain string or an array of content blocks ({"type": "text", "text": ...}\ or {"type": "image_url", "image_url": ...}) per the standard OpenAI multimodal schema. The endpoint models \content\ as an enum with only a \ ext\ variant, so it rejects \image_url\ blocks.
Expected behavior
The endpoint should tolerate the standard OpenAI message schema:
- Accept (and ignore) the
efusal\ field on assistant messages. - Support the \image_url\ content-block variant, or at minimum degrade gracefully rather than failing the whole request.
Impact
Standard OpenAI-compatible clients (e.g. GitHub Copilot App BYOK) cannot be used against this endpoint without errors, even though the same request works against the official OpenAI API and other compatible endpoints.
Suggested fix
- Relax message deserialization to ignore unknown fields (remove \deny_unknown_fields, or explicitly allow
efusal: Option). - Model \content\ as a string-or-blocks union supporting \ ext\ and \image_url\ variants.
Reproduction
Configure the endpoint as an OpenAI-compatible BYOK provider in a standard client, then send any multi-turn conversation (triggers
efusal) or any message containing an image (triggers \image_url).
Related report on the Copilot App side: https://github.com/github/app/issues/2903
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.