sgl-project/sglang · error · ValueError

{finish_reason["message"]}

Error message

{finish_reason["message"]}

What it means

Raised by _handle_abort_finish_reason when a non-streaming request finishes with finish_reason type 'abort' and status_code 400 (BAD_REQUEST): the server rejected the request and the stored message is re-raised client-side as a ValueError inside _wait_one_response.

Source

Thrown at python/sglang/srt/managers/tokenizer_manager.py:1665

            out["meta_info"] = meta_info
        return out

    async def _handle_abort_finish_reason(
        self,
        out: dict,
        state: ReqState,
        is_stream: bool,
    ) -> Optional[dict]:
        """Returns the output dict to yield (stream abort), None for normal flow;
        raises ValueError/HTTPException for non-stream aborts."""
        finish_reason = out["meta_info"]["finish_reason"]

        if (
            finish_reason.get("type") == "abort"
            and finish_reason.get("status_code") == HTTPStatus.BAD_REQUEST
        ):
            if not is_stream:
                raise ValueError(finish_reason["message"])
            return out

        if finish_reason.get("type") == "abort" and finish_reason.get(
            "status_code"
        ) in (
            HTTPStatus.SERVICE_UNAVAILABLE,
            HTTPStatus.INTERNAL_SERVER_ERROR,
        ):
            # Delete the key to prevent resending abort request to the scheduler and
            # to ensure aborted request state is cleaned up.
            if state.obj.rid in self.rid_to_state:
                del self.rid_to_state[state.obj.rid]

            # Mark ongoing LoRA request as finished.
            if self.enable_lora and state.obj.lora_path:
                await self.lora_registry.release(state.obj.lora_id)
            if not is_stream:
                raise fastapi.HTTPException(

View on GitHub (pinned to 0132848349)

Solutions

  1. Read the wrapped message — it contains the underlying abort reason from the server
  2. Fix the root cause named in the message (prompt length, params, malformed input)
  3. For richer error metadata, use the streaming path or check response finish_reason/status fields

Example fix

# before
out = client.generate(prompt, sp)  # raises ValueError('...abort message...')
# after
try:
    out = client.generate(prompt, sp)
except ValueError as e:
    logger.error('server rejected request: %s', e); raise
Defensive patterns

Strategy: try-catch

Validate before calling

if resp.get('finish_reason', {}).get('type') == 'abort':
    raise for streamed path / inspect finish_reason['message'] before using output

Try / catch

try:
    out = await tokenizer_manager._wait_one_response(rid, request_types, stream)
except ValueError as e:
    # e.args[0] is the server's abort message; log and surface to caller
    raise HTTPBadRequest(detail=str(e)) from e

Prevention

When it happens

Trigger: Non-streaming /generate call whose request is aborted by the scheduler/tokenizer with HTTP 400 — e.g. input validation failures, context-length overflow flagged as bad request — so finish_reason['message'] is surfaced by raising ValueError.

Common situations: Client sees a generic ValueError wrapping the server's abort message; common with over-length prompts, invalid sampling params, or other 400-class aborts on the non-stream path.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/ed4b96021dfd9d41. Report an issue: GitHub.