fix(xai-responses): strip enum values containing '/' from tool schemas#28021
Closed
Slimydog21 wants to merge 1 commit into
Closed
fix(xai-responses): strip enum values containing '/' from tool schemas#28021Slimydog21 wants to merge 1 commit into
Slimydog21 wants to merge 1 commit into
Conversation
xAI's /v1/responses and /v1/chat/completions reject tool schemas whose
enum values contain a forward slash with a generic HTTP 400 "Invalid
arguments passed to the model." before any token is emitted — the
schema compiler appears to trip on the '/' character regardless of where
it appears.
Most commonly hit by MCP-derived tools whose enum lists HuggingFace IDs
("Qwen/Qwen3.5-0.8B", "openai/gpt-oss-20b") or owner/name environment
identifiers. Reproduces against the live API; verified by isolating the
single offending tool from a 40-tool request body and bisecting the
schema keyword:
enum: ["foo", "bar"] -> 200
enum: ["Qwen/...", "openai/..."] -> 400
Mirrors the existing strip_pattern_and_format sanitizer wired up at the
codex_responses code path for is_xai_responses. The new strip_slash_enum
walks tool parameters and drops the entire enum keyword when any value
contains '/' — keeping it partial would still 400 since xAI's failure is
all-or-nothing on the enum. The field description still reaches the
model so the prompting hint is preserved.
Adds 9 unit tests covering: HF-style IDs, slashless enums (preserved),
partial-match (whole-enum stripped), Responses-format (no `function`
wrapper), anyOf recursion, idempotency, empty/None inputs, and
non-string enum values.
Contributor
Author
|
I am a vibe coder and code may be bad; have mercy with me. Just found out that my PrimeIntellect stuff had some conflicts with the XAI integration. Hope this is useful to someone ... |
Collaborator
Contributor
Author
teknium1
pushed a commit
that referenced
this pull request
May 18, 2026
xAI's /v1/responses and /v1/chat/completions endpoints reject tool schemas
whose enum values contain a forward slash with a generic HTTP 400 'Invalid
arguments passed to the model.' before any token is emitted — the schema
compiler trips on the '/' character regardless of where it appears.
Most commonly hit by MCP-derived tools whose enum lists HuggingFace model
IDs ('Qwen/Qwen3.5-0.8B', 'openai/gpt-oss-20b') or owner/name environment
identifiers.
Mirrors the existing strip_pattern_and_format sanitizer (PR for #27197).
The new strip_slash_enum walks tool parameters and drops the entire enum
keyword when any value contains '/' — keeping it partial would still 400
since xAI's failure is all-or-nothing on the enum. The field description
still reaches the model so the prompting hint is preserved.
Wired in at both code paths for parity:
- agent/chat_completion_helpers.py (main agent xAI Responses path)
- agent/auxiliary_client.py (aux client xAI Responses path, matching
the same parity guarantee 2fae8fb established for pattern/format)
Salvaged from #28021 by @Slimydog21 — contributor's branch was severely
stale (would have reverted ~5000 LOC across azure/kanban/i18n); fix
re-applied surgically on current main with their sanitizer + 9 tests
preserved verbatim. Author noreply email used (original was a Mac
hostname leak).
Contributor
|
Salvaged via #28122 — same severely-stale-branch situation as #27911/#28003 (would have reverted ~5000 LOC unrelated). Sanitizer + 9 tests preserved verbatim, plus wired in the auxiliary_client.py parity path the verdict noted was missing. You remain the commit author (used noreply email — your original commit leaked a Mac hostname). Thanks! |
Lillard01
pushed a commit
to Lillard01/hermes-agent
that referenced
this pull request
May 21, 2026
xAI's /v1/responses and /v1/chat/completions endpoints reject tool schemas
whose enum values contain a forward slash with a generic HTTP 400 'Invalid
arguments passed to the model.' before any token is emitted — the schema
compiler trips on the '/' character regardless of where it appears.
Most commonly hit by MCP-derived tools whose enum lists HuggingFace model
IDs ('Qwen/Qwen3.5-0.8B', 'openai/gpt-oss-20b') or owner/name environment
identifiers.
Mirrors the existing strip_pattern_and_format sanitizer (PR for NousResearch#27197).
The new strip_slash_enum walks tool parameters and drops the entire enum
keyword when any value contains '/' — keeping it partial would still 400
since xAI's failure is all-or-nothing on the enum. The field description
still reaches the model so the prompting hint is preserved.
Wired in at both code paths for parity:
- agent/chat_completion_helpers.py (main agent xAI Responses path)
- agent/auxiliary_client.py (aux client xAI Responses path, matching
the same parity guarantee 2fae8fb established for pattern/format)
Salvaged from NousResearch#28021 by @Slimydog21 — contributor's branch was severely
stale (would have reverted ~5000 LOC across azure/kanban/i18n); fix
re-applied surgically on current main with their sanitizer + 9 tests
preserved verbatim. Author noreply email used (original was a Mac
hostname leak).
Mucky010
pushed a commit
to Mucky010/hermes-agent
that referenced
this pull request
May 24, 2026
xAI's /v1/responses and /v1/chat/completions endpoints reject tool schemas
whose enum values contain a forward slash with a generic HTTP 400 'Invalid
arguments passed to the model.' before any token is emitted — the schema
compiler trips on the '/' character regardless of where it appears.
Most commonly hit by MCP-derived tools whose enum lists HuggingFace model
IDs ('Qwen/Qwen3.5-0.8B', 'openai/gpt-oss-20b') or owner/name environment
identifiers.
Mirrors the existing strip_pattern_and_format sanitizer (PR for NousResearch#27197).
The new strip_slash_enum walks tool parameters and drops the entire enum
keyword when any value contains '/' — keeping it partial would still 400
since xAI's failure is all-or-nothing on the enum. The field description
still reaches the model so the prompting hint is preserved.
Wired in at both code paths for parity:
- agent/chat_completion_helpers.py (main agent xAI Responses path)
- agent/auxiliary_client.py (aux client xAI Responses path, matching
the same parity guarantee 2fae8fb established for pattern/format)
Salvaged from NousResearch#28021 by @Slimydog21 — contributor's branch was severely
stale (would have reverted ~5000 LOC across azure/kanban/i18n); fix
re-applied surgically on current main with their sanitizer + 9 tests
preserved verbatim. Author noreply email used (original was a Mac
hostname leak).
gweeteve
pushed a commit
to gweeteve/hermes-agent
that referenced
this pull request
Jun 2, 2026
xAI's /v1/responses and /v1/chat/completions endpoints reject tool schemas
whose enum values contain a forward slash with a generic HTTP 400 'Invalid
arguments passed to the model.' before any token is emitted — the schema
compiler trips on the '/' character regardless of where it appears.
Most commonly hit by MCP-derived tools whose enum lists HuggingFace model
IDs ('Qwen/Qwen3.5-0.8B', 'openai/gpt-oss-20b') or owner/name environment
identifiers.
Mirrors the existing strip_pattern_and_format sanitizer (PR for NousResearch#27197).
The new strip_slash_enum walks tool parameters and drops the entire enum
keyword when any value contains '/' — keeping it partial would still 400
since xAI's failure is all-or-nothing on the enum. The field description
still reaches the model so the prompting hint is preserved.
Wired in at both code paths for parity:
- agent/chat_completion_helpers.py (main agent xAI Responses path)
- agent/auxiliary_client.py (aux client xAI Responses path, matching
the same parity guarantee 2fae8fb established for pattern/format)
Salvaged from NousResearch#28021 by @Slimydog21 — contributor's branch was severely
stale (would have reverted ~5000 LOC across azure/kanban/i18n); fix
re-applied surgically on current main with their sanitizer + 9 tests
preserved verbatim. Author noreply email used (original was a Mac
hostname leak).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
xAI's
/v1/responsesand/v1/chat/completionsreject tool schemas whoseenumvalues contain a forward slash with a generic HTTP 400Invalid arguments passed to the model.— emitted as the first SSE frame on the streaming path, surfacing as_StreamErrorEventand then retry-exhaustion inrun_agent.py. The schema compiler trips on the/character regardless of where it appears in the enum value.This is hit most commonly by MCP-derived tools whose
enumlists HuggingFace model IDs (Qwen/Qwen3.5-0.8B,openai/gpt-oss-20b) orowner/nameenvironment identifiers — e.g. the prime-cli lab MCP server'smcp_prime_lab_train_modeltool.Adds a
strip_slash_enumsanitizer that mirrors the existingstrip_pattern_and_formatand is wired up at the sameis_xai_responsescall site inagent/chat_completion_helpers.py.Reproduction
Captured the live failure by spying on the request body sent to
https://api.x.ai/v1/responses, isolating the single offending tool from a 40-tool request, and bisecting the schema keyword against the live API:Replayed the captured 78 KB body against the live API with the new sanitizer applied: ✅ 200, real response.
Design notes
enumkeyword when any value contains/. Keeping a partial enum (slashless values only) would still 400 because xAI's failure is all-or-nothing on the keyword. The field description still reaches the model, so the prompting hint is preserved.{"function": {"parameters": …}}) and Responses-format ({"name": …, "parameters": …}) tool entries./).Test plan
tests/tools/test_schema_sanitizer.pysuite passes (40/40).hermes chat -q '…'withprovider: xai-oauth,model: grok-4.3, and theprime_labMCP server enabled — fails onmainwithInvalid arguments, succeeds on this branch.Files changed
tools/schema_sanitizer.py— newstrip_slash_enum(tools) -> (tools, count)function.agent/chat_completion_helpers.py— chains the new sanitizer alongsidestrip_pattern_and_formatin theis_xai_responsesbranch.tests/tools/test_schema_sanitizer.py— 9 new tests.