Skip to content

Claude API rejects JSON Schema with type arrays for nullable fields #92

@lmlynik

Description

@lmlynik

Problem

When using Chimp with Claude Code (or Claude API), optional fields generate invalid JSON Schema that Claude's API rejects with:

API Error: 400 tools.X.custom.input_schema: JSON schema is invalid. 
It must match JSON Schema draft 2020-12

Root Cause

In McpHandler.scala line 58, TapirSchemaToJsonSchema is called with markOptionsAsNullable = true:

val base = TapirSchemaToJsonSchema(tool.inputSchema, markOptionsAsNullable = true)

This generates schemas like:

{
  "userId": {
    "type": ["integer", "null"],
    "format": "int64"
  }
}

While ["integer", "null"] is technically valid JSON Schema 2020-12, Claude's API validator does not support this syntax. Claude's API expects optional fields to be indicated by:

  1. NOT being in the required array
  2. Having a simple type like "type": "integer"

Evidence

Claude's own tool documentation shows all examples use simple types without null arrays. Their structured outputs documentation lists supported JSON Schema features, and type arrays for nullable fields are not among them.

Similar issue was reported in #23 for the $schema field, which was resolved by adding the showJsonSchemaMetadata option.

Proposed Fix

Change markOptionsAsNullable = true to markOptionsAsNullable = false on line 58 of McpHandler.scala:

val base = TapirSchemaToJsonSchema(tool.inputSchema, markOptionsAsNullable = false)

This will generate:

  • Option[Long]"type": "integer" (NOT in required array)
  • Long"type": "integer" (IN required array)

The optionality is correctly conveyed through the required array instead of type arrays.

Affected Clients

  • Claude Code
  • Claude API (Messages API with tools)
  • Potentially other MCP clients that use similar JSON Schema validation

Workaround

Currently users cannot work around this issue without modifying Chimp source code, as the parameter is hardcoded.

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