Skip to content

fix: surface xAI API errors instead of silently returning empty results#155

Open
km-git007 wants to merge 3 commits intomvanhorn:mainfrom
km-git007:fix/xai-silent-empty-response-errors
Open

fix: surface xAI API errors instead of silently returning empty results#155
km-git007 wants to merge 3 commits intomvanhorn:mainfrom
km-git007:fix/xai-silent-empty-response-errors

Conversation

@km-git007
Copy link
Copy Markdown

What

The xAI X (Twitter) search pipeline was silently discarding malformed or empty API responses. This caused users to receive incomplete research outputs without any error notification.

When the xAI API returned a 200 OK response with invalid or incomplete JSON (e.g., missing output text, malformed structure, or a missing "items" key), the parser would return an empty items list. Consequently, the orchestrator would incorrectly treat this as "zero relevant results found" rather than an "API failure."

Why

The root cause was that parse_x_response() returned early on malformed responses without raising exceptions. This violated the error-propagation contract; callers could not distinguish between a successful search with no results and an API that returned garbage data.

Note

This fix mirrors the approach taken in commit 7c9fd96 for the Codex authentication path (Reddit), ensuring consistency across our search parsers.

How

The fix implements the following changes:

  1. xai_x.py: Modified parse_x_response() to explicitly raise an HTTPError when:
    • Output text is empty.
    • The JSON structure lacks the expected "items" key.
    • The JSON syntax itself is malformed.
  2. last30days.py: Wrapped the parse_x_response() call inside the existing try-except block. This ensures parsing errors propagate as an x_error to the UI, informing the user of the failure.

Testing

  • Unit tests: Verified that valid responses parse correctly while malformed responses now successfully raise an HTTPError.
  • Integration tests: Confirmed that errors propagate through the orchestrator and set the x_error state correctly.
  • Error Messages: Added a response preview to the error output to assist with future debugging.

Notes for Reviewer

  • This is a direct port of the logic used in commit 7c9fd96 (Codex path fix) for architectural consistency.
  • Out of Scope: The Bird and ScrapeCreators X search backends share this "parsing-outside-try-except" pattern; however, they remain untouched in this PR to keep the scope focused on xAI.
  • UI Impact: Errors surface via the existing progress.show_error() channel. No new UI components were required.

Kaustav Mishra added 3 commits April 3, 2026 19:23
…ults

When Codex API returns an empty or malformed SSE response, the parsing
function was silently returning an empty dict, which then resulted in zero
Reddit search results being delivered to the user with no error indication.

This is a silent failure scenario where:
- User runs /last30days with Codex auth configured
- API returns empty/malformed response (network error, invalid format)
- Code silently treats it as 'search found zero results'
- User receives degraded research output with no error message

The fix adds explicit error handling:
- Raise HTTPError if SSE stream is completely empty (no events parsed)
- Raise HTTPError if stream has events but produces no output text
- These exceptions propagate through search_reddit() which already has
  proper exception handling that sets reddit_error and surfaces it to UI

The exceptions are caught by the existing error handlers at:
- search_reddit() line 312-320 (Codex auth path)
- search_reddit() line 341-350 (API key fallback path)

Both paths set reddit_error which bubbles up to the orchestrator and is
displayed to the user via progress.show_error().

Tests updated:
- test_codex_auth.py: Updated test_empty_stream to expect HTTPError
- test_codex_auth.py: Added test_malformed_stream_no_output to cover
  the case where SSE events exist but produce no output text

All 23 existing Codex auth tests continue to pass.
When xAI API returns an empty or malformed response (missing output text,
invalid JSON structure, malformed JSON syntax), the parse_x_response() function
was silently returning an empty items list, resulting in zero X search results
delivered to the user with no error indication.

This is a silent failure scenario where:
- User runs /last30days with xAI_API_KEY configured
- API returns empty/malformed response (network error, invalid format)
- Code silently treats it as 'search found zero results'
- User receives degraded research output with no error message

The fix adds explicit error handling:
- Raise HTTPError if output text is empty (no results or API failure)
- Raise HTTPError if JSON parsing fails (malformed structure)
- Raise HTTPError if output text lacks items key (wrong response format)
- These exceptions propagate through search_x() which already has proper
  exception handling that sets x_error and surfaces it to UI

The exceptions are caught by the existing error handlers in last30days.py
(lines 393-398) which set x_error that bubbles up to the orchestrator and is
displayed to the user via progress.show_error().

This mirrors the fix applied to Codex auth path in commit 7c9fd96.
Move parse_x_response() call inside the try-except block so that HTTPError
exceptions raised by the parsing function (due to malformed API responses)
are properly caught and x_error is set.

This ensures that parsing errors from empty/malformed xAI responses are
surfaced to the user instead of propagating uncaught.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant