Skip to content

fix(tools): strip xAI-unsupported JSON Schema keywords from tool definitions#32080

Merged
steipete merged 1 commit intoopenclaw:mainfrom
asyncjason:fix/xai-schema-validation-keywords
Mar 2, 2026
Merged

fix(tools): strip xAI-unsupported JSON Schema keywords from tool definitions#32080
steipete merged 1 commit intoopenclaw:mainfrom
asyncjason:fix/xai-schema-validation-keywords

Conversation

@asyncjason
Copy link

@asyncjason asyncjason commented Mar 2, 2026

Root cause

xAI models (via OpenRouter) reject tool call requests with "Invalid arguments passed to the model" / HTTP 502 when tool schemas contain JSON Schema validation-constraint keywords. Per the xAI structured outputs docs, the following keywords are not supported: minLength, maxLength, minItems, maxItems, minContains, maxContains. The sessions_spawn tool's attachment fields use several of these, causing every request to xAI models to fail.

Note re #32039 and #32054: Skipping reasoning.effort injection was investigated first and did not resolve the error. The actual cause is the JSON Schema keywords in tool definitions.

Fix

Follows the existing cleanSchemaForGemini pattern:

  • src/agents/schema/clean-for-xai.tsstripXaiUnsupportedKeywords() recursively removes the unsupported keywords from tool schemas; isXaiProvider() detects direct xAI providers and openrouter + x-ai/ model prefix
  • src/agents/pi-tools.schema.tsnormalizeToolParameters() extended with modelId option; new applyProviderCleaning() helper dispatches Gemini/xAI/passthrough
  • src/agents/pi-tools.ts — threads modelId through to normalizeToolParameters
  • src/agents/schema/clean-for-xai.test.ts — unit tests for detection and keyword stripping

Test plan

  • Unit tests: src/agents/schema/clean-for-xai.test.ts — covers isXaiProvider() detection (direct xAI, x-ai provider string, OpenRouter + x-ai/ prefix, non-xAI cases) and stripXaiUnsupportedKeywords() (string props, array props, minContains/maxContains, nested objects, anyOf/oneOf/allOf variants, array item schemas, passthrough of non-affected keywords)
  • isXaiProvider returns true for direct xai, x-ai, and openrouter + x-ai/ model prefix; false for openai, google, undefined
  • E2E: tool call to xAI model (via OpenRouter) succeeds without HTTP 502

Coded by Claude Code (claude-sonnet-4-6), reviewed and tested by @asyncjason

Fixes #32039

…nitions

xAI rejects minLength, maxLength, minItems, maxItems, minContains, and
maxContains in tool schemas with a 502 error instead of ignoring them.
This causes all requests to fail when any tool definition includes these
validation-constraint keywords (e.g. sessions_spawn uses maxLength and
maxItems on its attachment fields).

Add stripXaiUnsupportedKeywords() in schema/clean-for-xai.ts, mirroring
the existing cleanSchemaForGemini() pattern. Apply it in normalizeToolParameters()
when the provider is xai directly, or openrouter with an x-ai/* model id.

Fixes tool calls for x-ai/grok-* models both direct and via OpenRouter.
@openclaw-barnacle openclaw-barnacle bot added agents Agent runtime and tooling size: M labels Mar 2, 2026
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 2, 2026

Greptile Summary

This PR fixes 502 errors when using xAI models (including via OpenRouter) by stripping JSON Schema validation keywords that xAI doesn't support. The implementation follows the existing cleanSchemaForGemini pattern:

Key changes:

  • New clean-for-xai.ts module that recursively removes minLength, maxLength, minItems, maxItems, minContains, and maxContains from tool schemas
  • isXaiProvider() detects both direct xAI providers and OpenRouter + x-ai/ model prefix combinations
  • applyProviderCleaning() helper consolidates provider-specific schema cleaning logic
  • modelId parameter threaded through the tool normalization pipeline
  • Comprehensive test coverage for all stripping and detection logic

Why this works:
The sessions_spawn tool uses maxLength: 6_700_000 on attachment content fields and maxItems: 50 on attachment arrays. These constraint keywords cause xAI to reject requests with "Invalid arguments passed to the model" errors. The recursive stripping handles these nested cases correctly (properties → array items → object properties).

Confidence Score: 5/5

  • Safe to merge - well-tested fix following established patterns
  • The implementation mirrors the proven cleanSchemaForGemini pattern, includes comprehensive unit tests covering detection logic and recursive keyword stripping, addresses a specific documented issue, maintains backwards compatibility with optional parameters, and has been tested by the author. The changes are minimal, focused, and follow existing code conventions.
  • No files require special attention

Last reviewed commit: d888bd6

@steipete steipete merged commit 00347bd into openclaw:main Mar 2, 2026
29 checks passed
@steipete
Copy link
Contributor

steipete commented Mar 2, 2026

Landed via temp rebase onto main.

  • Gate: pnpm test src/agents/schema/clean-for-xai.test.ts
  • Land commit: 1b0728f
  • Merge commit: 00347bd

Thanks @asyncjason!

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

Labels

agents Agent runtime and tooling size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: error when sending a request to x-ai/grok-4.1-fast via OpenRouter

2 participants