Skip to content

Console Go (Meta Muse Spark): MCP tool schemas deeper than 10 levels are rejected, no Meta/Muse sanitizer #50297

Closed as not planned

Description

@satyalyadav

Summary

Muse Spark via OpenCode Go fails on the first request when any tool schema nests deeper than 10 levels. The provider rejects the whole request, not just the offending tool.

Error from provider (Console Go): Upstream request failed: [invalid_request_error] JSON schema exceeds the maximum nesting depth of 10 levels
  • Endpoint: https://opencode.ai/zen/go/v1/responses
  • Model: muse-spark-1.3-contributor (provider opencode-go)
  • Provider response body: {"model":"muse-spark-1.3-contributor","error":{"param":"parameters","type":"invalid_request_error","message":"Error from provider (Console Go): Upstream request failed: [invalid_request_error] JSON schema exceeds the maximum nesting depth of 10 levels"}}
  • opencode 1.18.31

Other models on the same provider (for example deepseek-v4.1-flash) accept the same tool schemas, so this only breaks on strictly validating upstreams.

Reproduction

  1. Enable an MCP server with deep tool schemas. The public Vercel MCP server (https://mcp.vercel.com) is a minimal example. I measured all 212 published inputSchemas by counting object/array member recursion (properties, items, additionalProperties, anyOf, oneOf, allOf, $defs). Twelve reach depth 10 or more:
tool depth bytes deepest path
create_flag 14 10234 .requestBody.environments.oneOf[0].additionalProperties.rules.items.conditions.items.rhs.anyOf[0].items.items.anyOf[0].label
update_flag 13 10346 .requestBody.environments.additionalProperties.rules.items.conditions.items.rhs.anyOf[0].items.items.anyOf[0].label
update_sandbox 12 14775 .requestBody.networkPolicy.oneOf[1].allow.oneOf[1].additionalProperties.items.match.queryString.items.key.exact
update_flag_segment 12 4471 .requestBody.data.rules.items.conditions.items.rhs.anyOf[0].items.items.anyOf[0].label
create_sandboxes_v4 12 17019 .requestBody.networkPolicy.oneOf[1].allow.oneOf[1].additionalProperties.items.match.queryString.items.key.exact
create_sandboxes_v3 12 16836 .requestBody.networkPolicy.oneOf[1].allow.oneOf[1].additionalProperties.items.match.queryString.items.key.exact
create_sandboxes_v2 12 17156 .requestBody.networkPolicy.oneOf[1].allow.oneOf[1].additionalProperties.items.match.queryString.items.key.exact
update_session_network_policy 11 10708 .requestBody.oneOf[1].allow.oneOf[1].additionalProperties.items.match.queryString.items.key.exact
update_project 11 24296 .requestBody.trustedSources.anyOf[0].projects.additionalProperties.customAllow.items.to.anyOf[0].slugs.items
put_firewall_config 11 9543 .requestBody.rules.items.action.mitigate.rateLimit.anyOf[0].anyOf[0].action.anyOf[0].anyOf[0]
update_firewall_config 10 19348 .requestBody.oneOf[0].value.conditionGroup.items.conditions.items.value.anyOf[1].items
create_connector 10 53316 .requestBody.anyOf[0].data.anyOf[0].serverConfig.jwks.keys.items.key_ops.items
  1. Config:
{
  "mcp": {
    "vercel": { "type": "remote", "url": "https://mcp.vercel.com", "enabled": true, "oauth": {} }
  }
}
  1. opencode run -m opencode-go/muse-spark-1.3-contributor "Reply with exactly: ok" fails with the error above.
  2. The same command with "mcp": {} returns ok.
  3. The same command with only the Vercel MCP enabled fails again, so the MCP server is the trigger.

Cause

packages/opencode/src/provider/transform.ts has per-provider schema sanitizers for OpenAI, Moonshot/Kimi, and Gemini, but nothing Meta/Muse-shaped. MCP tool schemas are forwarded as published, so any MCP server over the limit breaks every Muse Spark session. Meta's Model API rejects both recursive $ref (#45800, #48151) and schemas over its nesting limit.

Ask

Add a Meta/Muse-bound sanitizer that flattens tool schemas under the provider's nesting limit and strips recursive $ref, the same way the other providers are handled.

Workaround

Disable the offending MCP server for Muse Spark. A dedicated agent keeps the server available for other models:

{
  "agent": {
    "muse": {
      "mode": "primary",
      "model": "opencode-go/muse-spark-1.3-contributor",
      "permission": { "vercel_*": "deny" }
    }
  }
}

Related

Activity

  1. argszero commented on Sep 21, 2026

    @argszero
    Contributor

    I'd like to work on this.

    This looks like a real gap in the provider-specific sanitizers: packages/opencode/src/provider/transform.ts already has per-provider schema passes (sanitizeOpenAISchema, plus the Moonshot and Gemini passes) that drop unsupported keywords, but nothing bounds nesting depth, so one deeply nested MCP inputSchema fails the entire request on a strictly validating upstream instead of just degrading that tool.

    Plan:

    1. Add a depth-bounded schema pass for providers whose upstream rejects deep schemas, walking properties / items / additionalProperties / $defs / anyOf / oneOf / allOf, and replacing nodes that exceed the limit with a permissive subschema instead of forwarding the offending tree.
    2. Cover it with a unit test in packages/opencode/test/provider/transform.test.ts using a fixture at depth >= 10 (shape modelled on the measured Vercel create_flag schema), asserting the emitted schema respects the limit and stays a valid JSON Schema.
    3. Verify with a mocked provider call only — no live upstream requests.

    One question on scope, so the change lands in the shape you prefer: should the depth cap be scoped to the Console Go provider (mirroring the existing opencode-go special cases), or would you rather have a per-provider option under provider.options so any upstream limit can be configured? I will default to the provider-scoped approach unless you say otherwise, and keep the change small and additive.

  2. argszero commented on Sep 21, 2026

    @argszero
    Contributor

    Opened #50320 with a Meta/Muse schema pass in packages/opencode/src/provider/transform.ts.

    It runs for the meta provider and for Muse models on the opencode gateways (opencode, opencode-go), and keeps tool schemas within the nesting limit by dropping the members that would nest past it — properties, items, additionalProperties, anyOf/oneOf/allOf, $defs/definitions — while keeping every other keyword on the node. Depth is counted as in the report: the parameter root is level 0, so the deepest surviving schema is 9 steps below it (10 levels counting the root), matching the tools reported as failing at depth 10.

    Recursive $ref (#45800, #48151) is a separate concern and is not touched by this PR.

  3. thdxr commented on Oct 11, 2026

    @thdxr
    Member

    Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.

    — from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊

  4. satyalyadav commented on Oct 12, 2026

    @satyalyadav
    Author

    Follow-up per the 2.0 ask: still relevant on v2.0.26, with one nuance.

    Repro on 2.0: a local MCP server with a tool schema nested 12 levels deep, model opencode-go/muse-spark-1.3-contributor, server exposed natively (codemode: false) fails with JSON schema exceeds the maximum nesting depth of 10 levels. With Code Mode at its default (MCP tools exposed through Code Mode), the same setup passes, since the deep schema never reaches Meta.

    The fix is in flight: #51040 (fix(ai): keep tool schemas within Meta's limits) adds the meta sanitizer for nesting depth and recursive $ref, covering this issue, #45800, and #48151. It is open and currently needs a rebase against dev. Tracking it there rather than opening a duplicate 2.0 issue.

  5. p30arena commented on Oct 16, 2026

    @p30arena

    I disabled MCPs, and the issue is gone

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions