- 
        Couldn't load subscription status. 
- Fork 2.4k
fix: skip JSON fallback when web_search tool is present #8963
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
fix: skip JSON fallback when web_search tool is present #8963
Conversation
| I don't think the issue is limited to the specific tool. Can we just add a warning log in the fallback block? | 
| @TomeHirata You're absolutely right - a warning log is a much better approach! I've updated the PR to add a warning log that displays the original error before attempting JSON fallback. This: 
 The warning now shows: This gives developers full context to debug the root cause. Thanks for the feedback! | 
| Why are there so many diffs? I only expect one line addition for a warning. | 
- Add import logging at top of file - Log error type and message before JSON fallback - Minimal change - only adds warning log (6 insertions, 1 deletion) - Addresses @TomeHirata feedback for clean diff Signed-off-by: Bhaskar <bhaskar@zasti.ai>
806304d    to
    d28edff      
    Compare
  
    | # On context window exceeded error or already using JSONAdapter, we don't want to retry with a different | ||
| # adapter. | ||
| raise e | ||
| logger = logging.getLogger(__name__) | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's defind the logger on the module level
| logger = logging.getLogger(__name__) | ||
| logger.warning( | ||
| f"Structured output failed with error: {type(e).__name__}: {str(e)[:200]}. " | ||
| f"Falling back to JSON mode." | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's call it as JSONAdapter to clarify
| # adapter. | ||
| raise e | ||
| logger = logging.getLogger(__name__) | ||
| logger.warning( | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can simply use e without custom formatting
Description
Fixes #8958
When using tools with
type: "web_search", theChatAdapterwas falling back to JSON mode after the initial structured output attempt failed. This caused a misleading error message that masked the actual underlying error.Problem
The current error flow was:
This masked the real error from step 1, making debugging very difficult.
Solution
Added detection for
web_searchtools inlm_kwargsbefore attempting JSON fallback. When web_search is present, the adapter now skips the JSON fallback and raises the original error instead.Changes
Modified:
dspy/adapters/chat_adapter.pyweb_searchtools before JSON fallback (lines 47-53)toolswithtype: "web_search"inlm_kwargsWhy This Improves Error Handling
Before this fix:
❌ Confusing - makes developers think the issue is JSON mode compatibility
After this fix:
✅ Clear - shows the actual error that needs to be addressed
Testing
Tested with a reproduction script:
tools=[{"type": "web_search"}]Related Discussion
This addresses the concern raised by @chenmoneygithub:
This implementation automatically detects
web_searchand skips the retry, solving the issue without requiring manual configuration.Additional Notes
Users may still encounter errors when using
web_search(e.g., if using incompatible model types), but they'll now see the actual error instead of a misleading JSON mode error. This significantly improves the debugging experience.