anomalyco / anomalyco/opencode
kimi-k3 (Moonshot) always fails with `Upstream request failed` - tool schemas containing $ref are rejected
@kitlangton is already working on this.
Since Aug 1, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Describe the bug
When using kimi-k3 (Moonshot) via OpenCode Go, every conversation with tools enabled fails immediately with:
Error from provider (Console Go): Upstream request failed
The exact same configuration works fine with glm-5.2, grok-4.5, deepseek-*. This is not a config/auth/region issue — it is model-specific to Moonshot.
Root cause (confirmed by direct API testing against the provider gateway)
Moonshot's upstream API rejects tool definitions containing:
$ref— even a bare{"$ref": "#/components/schemas/Foo"}with no sibling keys is rejected- tuple-style
itemsarrays —"items": ["string", "number"]is rejected
opencode's sanitizeMoonshot sanitizer (packages/opencode/src/session/transform.ts, ~line 1524-1540) removes sibling keys of $ref and converts tuple items to items[0], but keeps the $ref itself. After sanitization the tool schema still contains $ref, which Moonshot still rejects — so the sanitizer never actually fixes the request.
Other providers (Zhipu/GLM, xAI/Grok) accept the same tool schemas, which is why only Moonshot models break.
Reproduction
- Configure a Moonshot-backed model (e.g.
kimi-k3) through any OpenAI-compatible gateway - Start any conversation — the main agent always includes tool definitions
- Every request fails with
Upstream request failed
Direct API test (same key + baseURL, only the tool schema differs):
| request body | kimi-k3 (Moonshot) | glm-5.2 (Zhipu) |
|---|---|---|
simple tool, no $ref |
✅ 200 stream | ✅ 200 stream |
tool with anyOf |
✅ 200 stream | ✅ 200 stream |
tool with tuple items: ["string","number"] |
❌ upstream request failed | ✅ 200 stream |
tool with bare $ref (no siblings) |
❌ upstream request failed | ✅ 200 stream |
Expected behavior
kimi-k3 (and other Moonshot models) should work in tool-enabled conversations, like glm-5.2 / grok-4.5 do.
Suggested fix
sanitizeMoonshot must strip $ref entirely, not just its sibling keys — Moonshot rejects even a bare $ref. Either:
- resolve
$refto the actual schema before sending, or - drop properties that are pure
$refreferences
Environment
- OS: Windows
- Provider: OpenCode Go (
https://opencode.ai/zen/go/v1) - Model:
kimi-k3
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.