fix(providers): Responses API tool schema and null error handling#790
Merged
DonPrus merged 1 commit intonullclaw:mainfrom Apr 16, 2026
Merged
Conversation
f993872 to
a1d8d4f
Compare
Fix two bugs in the Responses API (api_mode=responses) code path:
1. Tool schema format: buildResponsesRequestBody used convertToolsOpenAI
which produces nested Chat Completions format
({"type":"function","function":{"name":...}}). Responses API
requires flat format ({"type":"function","name":...}).
- Add convertToolsResponses() in helpers.zig producing flat format
- Wire into buildResponsesRequestBody (compatible.zig:548)
- Export convertToolsResponses in root.zig
2. Null error misclassification: classifyErrorObject returned .other
when response contained "error": null (JSON null), causing valid
responses to be rejected as API errors.
- Add null guard: if (err_value == .null) return null
Tests:
- convertToolsResponses produces flat format (no nested "function")
- convertToolsResponses empty tools
- classifyKnownApiError returns null for error:null
- parseResponsesResponse handles error:null without returning error
- buildResponsesRequestBody tools use flat schema (updated existing test)
Fixes nullclaw#773
c911359 to
95b5b2e
Compare
DonPrus
approved these changes
Apr 16, 2026
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
Fix two bugs in the OpenAI-compatible provider's Responses API (
api_mode=responses) code path:buildResponsesRequestBodyusedconvertToolsOpenAIwhich produces nested Chat Completions format ({"type":"function","function":{"name":...}}). Responses API requires flat format ({"type":"function","name":...}). AddedconvertToolsResponses()producing the correct flat format.classifyErrorObjectreturned.otherwhen response contained"error": null(JSON null), causing valid responses to be rejected as API errors. Added null guard before the.objectcheck.Changes
src/providers/helpers.zigconvertToolsResponses()— flat tool schema formatsrc/providers/root.zigconvertToolsResponsessrc/providers/compatible.zig:548convertToolsResponsesintobuildResponsesRequestBodysrc/providers/error_classify.zig:312if (err_value == .null) return null;Tests
convertToolsResponses produces flat format— verifies no nested"function"wrapper,"name"at top levelconvertToolsResponses empty tools— verifies[]for empty inputclassifyKnownApiError returns null for error:null— verifies null error is not classifiedparseResponsesResponse handles error:null without returning error— verifies content extraction despite null errorbuildResponsesRequestBody includes tools and tool results— adds flat format assertionsValidation
zig build— compiles cleanzig fmt --check src/— passesApproach Comparison
This PR addresses the same bugs as #772 (@telagod). Both share the same fix approach:
convertToolsResponsesclassifyErrorObjectbuildResponsesRequestBodyconvertToolsResponses"error": nullclassificationparseResponsesResponsewith null errorThis PR is functionally equivalent to #772 but adds test coverage for both fixes (5 new tests + 1 updated), following the repo's mandate that "every code change must be accompanied by tests, no exceptions" (AGENTS.md §8.1).
Supersedes
Supersedes #772 — identical production fix + comprehensive test coverage.
Fixes #773