Skip to content

fix: prevent Gemini assistant crash on empty search query and non-JSON tool errors #85

Description

@vitorhugo-dotnet

Context

The ApplyWell assistant crashes during contextual follow-up questions when Gemini invokes searchApplications without a text query.

Observed flow:

  1. User asks for aggregate data, e.g. quantas vagas eu já me inscrevi na CWI?
  2. Assistant answers correctly using stats.
  3. User follows up with Alguma delas eu fiz entrevista?
  4. Gemini invokes searchApplications with structured context/filters but without query.
  5. AssistantApplicationQueryService.requiredQuery() throws IllegalArgumentException("query is required").
  6. Spring AI GoogleGenAiChatModel tries to parse the plain-text tool error as JSON and crashes in parseJsonToMap() / messageToGeminiParts().
  7. Frontend receives the generic The assistant is temporarily unavailable. state.

Evidence

Backend logs around 2026-09-15 21:49 BRT:

java.lang.RuntimeException: Failed to parse JSON: query is required
    at org.springframework.ai.google.genai.GoogleGenAiChatModel.parseJsonToMap(...)
    at org.springframework.ai.google.genai.GoogleGenAiChatModel.messageToGeminiParts(...)

Caused by: com.fasterxml.jackson.core.JsonParseException:
Unrecognized token 'query': was expecting JSON String, Number, Array, Object or token 'null', 'true' or 'false'

Relevant code:

  • AssistantTools.searchApplications(SearchInput input)
  • AssistantApplicationQueryService.search(...)
  • AssistantApplicationQueryService.requiredQuery(...)

Root causes

1. searchApplications requires query even when structured filters are sufficient

The tool exposes structured fields such as organization, status, platform, and date range, but the service always requires a non-empty query.

This makes contextual follow-ups fragile because the model may correctly preserve structured context without repeating the original search text.

2. Non-JSON tool failures are unsafe with Spring AI Google GenAI

Spring AI currently has an upstream issue where GoogleGenAiChatModel assumes tool responses are JSON and crashes on plain text:

Until that is fixed upstream, tool outputs/errors sent back to Gemini should be structured JSON-safe payloads.

Expected behavior

A contextual question such as:

User: quantas vagas eu já me inscrevi na CWI?
Assistant: Você já se inscreveu em 5 vagas na CWI.
User: Alguma delas eu fiz entrevista?

must complete successfully without requiring the model to repeat CWI as a free-text query.

Acceptance criteria

  • searchApplications accepts a null/blank query when at least one structured filter is present.
  • Validation rejects calls only when no searchable text and no meaningful structured filter are provided.
  • Tool errors/results returned to Gemini are JSON-safe while Spring AI issue #5437 remains unresolved.
  • Add regression test for structured search with query == null.
  • Add regression test for a contextual follow-up equivalent to Alguma delas eu fiz entrevista?.
  • Add test ensuring tool failures do not produce a non-JSON response that crashes GoogleGenAiChatModel.
  • Existing assistant search/stats behavior remains unchanged.
  • Frontend should receive a normal assistant response or a controlled application error, never a provider parsing exception.

Notes

Prefer fixing the tool contract and error serialization rather than forcing the prompt to always fabricate/repeat a text query. The tool schema should reflect what the backend actually supports, otherwise the model gets blamed for stepping on a rake we left in the hallway.

Activity

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

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions