MoonshotAI / MoonshotAI/kimi-code

bug: 400 "not a valid moonshot flavored json schema" when an MCP tool schema declares `type` next to `anyOf`

Open
#2,661 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
7.5k
Forks
1.2k
Avg merge
11h 53m
Merged PRs (30d)
350

Description

What version of Kimi Code is running?

0.33.0 (the schema-handling code is identical in 0.32.0, which is equally affected)

Which open platform/subscription were you using?

Kimi subscription, model kimi-code/k3

What happened?

With the official Notion MCP server connected, every prompt in the session immediately fails before the model produces any output:

Error: [provider.api_error] 400 tools.function.parameters is not a valid moonshot flavored json schema,
details: <At path 'root': when using anyOf, type should be defined in anyOf items instead of the parent schema>
Root cause

The Notion MCP server recently (around 2026-08-04) updated its notion-create-attachment tool. Its inputSchema root now declares type next to a three-way anyOf:

{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "Provide exactly one of the documented input variants.",
  "anyOf": [
    { "type": "object", "properties": { "filename": { "type": "string" }, "content": { "type": "string" } }, "required": ["filename", "content"] },
    { "type": "object", "properties": { "filename": { "type": "string" }, "source_url": { "type": "string" } }, "required": ["filename", "source_url"] },
    { "type": "object", "properties": { "source_file_id": { "type": "string" } }, "required": ["source_file_id"] }
  ]
}

This is valid JSON Schema, but Moonshot's tool validator rejects type declared next to anyOf (it wants the type inside the branches). Since the whole tools[] array is validated per request, one bad MCP tool schema bricks every prompt in the session.

Kimi Code currently cannot repair this shape:

  • MCP inputSchema is forwarded verbatim (assertMcpInputSchema only checks it is a plain object).
  • The Kimi schema normalizer (normalizeKimiToolSchema in kimi-schema.ts, both the kosong copy and the agent-core-v2 copy) treats the root as a container and never normalizes it, and skips any node containing combinator keywords (anyOf/oneOf/allOf are in TYPE_COMPLETION_SKIP_KEYS). No code path removes a type sitting next to a combinator.
  • Additionally, derefJsonSchema's $ref sibling-key merge can synthesize this exact shape from a root-level $ref whose definition is a union — so the problem is not limited to Notion.

Verified against captured wire logs: sessions from 2026-07-28 through 2026-08-03 show the same tool with a plain {type: "object", properties: ...} root (requests succeeded); sessions from 2026-08-05 onward show the anyOf + type root (requests fail with the 400 above). This is a third-party schema change colliding with a normalizer gap, not a CLI version regression — downgrading does not help.

Reproduction
  1. Connect any MCP server that publishes a tool whose inputSchema root contains both type and anyOf (the current official Notion MCP server does).
  2. Start a session with a Moonshot model (e.g. K3) and send any prompt.
  3. The request fails with the 400 above.

Minimal standalone check: pass the schema above through normalizeKimiToolSchema — the output still contains type next to anyOf.

Workaround

In ~/.kimi-code/mcp.json, exclude the offending tool:

"notion": { "url": "...", "disabledTools": ["notion-create-attachment"] }
Proposed fix

In normalizeKimiToolSchema (both copies), after $ref dereferencing and before type completion, walk every schema node including the root: when a node declares type next to anyOf/oneOf, copy the parent type into each branch that has no type of its own (and no combinator keywords), then drop it from the parent. This is exactly the shape Moonshot's validator asks for and preserves JSON Schema semantics (the parent constraint applied to every union branch anyway).

I have a PR ready with this fix plus regression tests (including a replay of all 102 tool schemas from the failing session: 1 violation before, 0 after, no changes to the other 101).

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.

Research direction

Start with normalizeKimiToolSchema in the kimi-schema.ts copies for kosong and agent-core-v2, then run the minimal schema check described in the issue. Trace inputSchema validation and $ref dereferencing before the type-completion logic. Done means schemas with a parent type beside anyOf, oneOf, or allOf no longer trigger the Moonshot validation error and the stated regression cases pass.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.