anomalyco / anomalyco/opencode

kimi-k3 (Moonshot) always fails with `Upstream request failed` - tool schemas containing $ref are rejected

Open
#39,995 1 comment 0 reactions 1 assignee View on GitHub

@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:

  1. $ref — even a bare {"$ref": "#/components/schemas/Foo"} with no sibling keys is rejected
  2. tuple-style items arrays — "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

  1. Configure a Moonshot-backed model (e.g. kimi-k3) through any OpenAI-compatible gateway
  2. Start any conversation — the main agent always includes tool definitions
  3. 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 $ref to the actual schema before sending, or
  • drop properties that are pure $ref references

Environment

  • OS: Windows
  • Provider: OpenCode Go (https://opencode.ai/zen/go/v1)
  • Model: kimi-k3

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.