Skip to content

fix: guard choices[0] and message=None before content access in llm_as_judge#1238

Open
qizwiz wants to merge 1 commit into
huggingface:mainfrom
qizwiz:fix/guard-unguarded-llm-choices
Open

fix: guard choices[0] and message=None before content access in llm_as_judge#1238
qizwiz wants to merge 1 commit into
huggingface:mainfrom
qizwiz:fix/guard-unguarded-llm-choices

Conversation

@qizwiz
Copy link
Copy Markdown

@qizwiz qizwiz commented May 17, 2026

Summary

In src/lighteval/metrics/utils/llm_as_judge.py, the API retry loop at line 439 accesses response.choices[0].message.content without checking:

  • Whether choices is non-empty (can be [] on API error or rate-limiting → IndexError)
  • Whether choices[0].message is non-None (Gemini returns None on PROHIBITED_CONTENT with HTTP 200 → AttributeError)

This fix adds the comprehensive guard:

if not response.choices or response.choices[0].message is None:
    raise ValueError("LLM returned empty or filtered response")

The ValueError is caught by the inner except Exception block that already handles API errors, so the retry logic continues as designed.

Static analysis via pact (Z3 Fixedpoint datalog, llm_response_unguarded rule); post-fix scan returns 0 violations.

…s_judge

OpenAI-compatible APIs can return empty choices on error or content
filtering; Gemini returns choices[0].message=None on PROHIBITED_CONTENT
(HTTP 200). Both cause unhandled exceptions inside the retry loop.

Adds guard before response.choices[0].message.content in the API call
retry path so the ValueError propagates cleanly.
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