Skip to content

fix(moonshot): normalise union type arrays in _fill_missing_type to prevent TypeError#30753

Open
SimoKiihamaki wants to merge 1 commit into
NousResearch:mainfrom
SimoKiihamaki:fix/30095-moonshot-union-type-list
Open

fix(moonshot): normalise union type arrays in _fill_missing_type to prevent TypeError#30753
SimoKiihamaki wants to merge 1 commit into
NousResearch:mainfrom
SimoKiihamaki:fix/30095-moonshot-union-type-list

Conversation

@SimoKiihamaki

Copy link
Copy Markdown
Contributor

Fix #30095

Problem

When using kimi-k2.6 (or any Moonshot model), any tool whose JSON Schema uses a union type array ("type": ["number", "string"]) causes a crash inside sanitize_moonshot_tools():

TypeError: unhashable type: 'list'

This is a hard crash — the agent cannot call any tool that has a union-typed parameter.

Root Cause

_fill_missing_type() in agent/moonshot_schema.py line 169:

if "type" in node and node["type"] not in {None, ""}:

When node["type"] is a Python list (e.g. ["number", "string"]), the not in {None, ""} set membership test raises TypeError because Python lists are not hashable.

Fix

Added a guard at the top of _fill_missing_type() that detects list types and normalises to the first concrete (non-null) type. Moonshot does not accept union type arrays anyway — it requires a single scalar type — so this is both correct and safe.

if isinstance(node_type, list):
    concrete = next(
        (t for t in node_type if t not in (None, "null", "")),
        "string",
    )
    return {**node, "type": concrete}

Testing

  • 7 new regression tests in TestUnionTypeList:
    • ["number", "string"]"number"
    • ["string", "integer"]"string"
    • ["null", "string"]"string" (null skipped)
    • ["null"]"string" (all-null fallback)
    • Key preservation (description, default)
    • Nested properties
    • Array items
  • All 49 tests pass (42 existing + 7 new)

…revent TypeError (Fixes NousResearch#30095)

When a JSON Schema property uses a union type array like
"type": ["number", "string"], the set membership test
node["type"] not in {None, ""} raises TypeError: unhashable
type 'list' because Python lists are not hashable.

Moonshot does not accept union type arrays anyway — it requires a
single scalar type.  Normalise to the first concrete (non-null) type
before the set membership check.

7 new regression tests covering: number|string, string|integer,
null|string, all-null, key preservation, nested properties, and
array items.
Copilot AI review requested due to automatic review settings May 23, 2026 04:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR fixes a crash in Moonshot schema sanitization when encountering JSON Schema union types expressed as type: [...] arrays, and adds regression tests to ensure union types are normalized deterministically.

Changes:

  • Normalize list-valued type fields (e.g., ["number", "string"]) to the first concrete non-null type.
  • Add regression tests covering union types in top-level properties, nested objects, and array items.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
agent/moonshot_schema.py Normalizes JSON Schema union-type arrays to a single Moonshot-compatible scalar type.
tests/agent/test_moonshot_schema.py Adds regression tests ensuring union-type arrays don’t crash and normalize correctly across nesting forms.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread agent/moonshot_schema.py
Comment on lines +174 to +183
node_type = node.get("type")
# Guard: list types (e.g. ["number", "string"]) are not hashable and
# cannot be tested with `not in {None, ""}`. Normalise to the first
# non-null element so the rest of the pipeline sees a plain string type.
if isinstance(node_type, list):
concrete = next(
(t for t in node_type if t not in (None, "null", "")),
"string",
)
return {**node, "type": concrete}
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/agent Core agent loop, run_agent.py, prompt builder provider/kimi Kimi / Moonshot duplicate This issue or pull request already exists labels May 23, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Duplicate of #28422 — only fixes the _fill_missing_type() crash site (L169), while #28422 fixes both crash sites (L147 _repair_schema + L169 _fill_missing_type). Also duplicates #30226 and #28322 which target the same bug. Root issue: #28291.

@saravanakumar-axl

saravanakumar-axl commented May 23, 2026 via email

Copy link
Copy Markdown

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

Labels

comp/agent Core agent loop, run_agent.py, prompt builder duplicate This issue or pull request already exists P2 Medium — degraded but workaround exists provider/kimi Kimi / Moonshot type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

kimi-k2.6: TypeError: unhashable type 'list' in sanitize_moonshot_tools when tool has union type parameter

4 participants