hiyouga/LlamaFactory · error · HTTPException

Invalid request

Error message

Invalid request

What it means

Raised as HTTP 400 by create_score_evaluation_response (the /v1/score or score-evaluation endpoint) when request.messages is an empty list. Scoring requires at least one prompt/response pair to evaluate; an empty body is rejected outright.

Source

Thrown at src/llamafactory/api/chat.py:291

        stop=request.stop,
    ):
        if len(new_token) != 0:
            yield _create_stream_chat_completion_chunk(
                completion_id=completion_id, model=request.model, delta=ChatCompletionMessage(content=new_token)
            )

    yield _create_stream_chat_completion_chunk(
        completion_id=completion_id, model=request.model, delta=ChatCompletionMessage(), finish_reason=Finish.STOP
    )
    yield "[DONE]"


async def create_score_evaluation_response(
    request: "ScoreEvaluationRequest", chat_model: "ChatModel"
) -> "ScoreEvaluationResponse":
    score_id = f"scoreval-{uuid.uuid4().hex}"
    if len(request.messages) == 0:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Invalid request")

    scores = await chat_model.aget_scores(request.messages, max_length=request.max_length)
    return ScoreEvaluationResponse(id=score_id, model=request.model, scores=scores)

View on GitHub (pinned to f28afaf635)

Solutions

  1. Ensure messages is non-empty before calling the endpoint; skip the call if the batch is empty.
  2. Log batch size upstream so empty batches are visible at the source.
  3. If you expect scores, verify you are hitting the right endpoint with the right schema rather than an intentionally empty probe.

Example fix

# before
scores = await client.score_evaluation(messages=batch)  # batch may be []
# after
if not batch:
    return []
scores = await client.score_evaluation(messages=batch)
Defensive patterns

Strategy: validation

Validate before calling

if len(batch) == 0:
    return []  # skip the call entirely
scores = client.score_evaluation(messages=batch)

Type guard

const hasMessages = (req) => Array.isArray(req.messages) && req.messages.length > 0;

Try / catch

catch (e) { if (e.status === 400 && e.detail === 'Invalid request' && !req.messages?.length) { return []; /* empty batch is fine client-side */ } throw e; }

Prevention

When it happens

Trigger: POST to the score evaluation endpoint with messages: []; a batch pipeline whose upstream filtering removed all items but still sent the request; default-constructed request object.

Common situations: Automated eval harnesses that skip the empty-batch check; data-loading bugs producing zero rows; testing the endpoint with a placeholder payload.

Related errors


AI-assisted analysis of hiyouga/LlamaFactory@f28afaf635 (2026-08-14). Data as JSON: /api/errors/7ecc14e335be41ac. Report an issue: GitHub.