sgl-project/sglang · error · ValueError

Duplicate request_id: {request_id}

Error message

Duplicate request_id: {request_id}

What it means

Raised by RequestStateStore.submit when a request_id already exists in the store. The store keys every in-flight request by a unique request_id, and re-submitting an id would corrupt state tracking, so duplicates are rejected at insertion time under the store's lock.

Source

Thrown at python/sglang/multimodal_gen/runtime/disaggregation/request_state.py:86

    def elapsed_s(self) -> float:
        return time.monotonic() - self.submit_time

    def is_terminal(self) -> bool:
        return self.state in _TERMINAL_STATES


class RequestTracker:
    """Thread-safe tracker for request state machines."""

    def __init__(self):
        self._lock = threading.Lock()
        self._requests: dict[str, RequestRecord] = {}

    def submit(self, request_id: str) -> RequestRecord:
        with self._lock:
            if request_id in self._requests:
                raise ValueError(f"Duplicate request_id: {request_id}")
            record = RequestRecord(request_id=request_id)
            self._requests[request_id] = record
            return record

    def transition(
        self,
        request_id: str,
        new_state: RequestState,
        *,
        error: str | None = None,
        encoder_instance: int | None = None,
        denoiser_instance: int | None = None,
        decoder_instance: int | None = None,
    ) -> RequestRecord:
        with self._lock:
            record = self._requests.get(request_id)
            if record is None:
                raise ValueError(f"Unknown request_id: {request_id}")

View on GitHub (pinned to 0132848349)

Solutions

  1. Generate globally unique request ids (UUID4) per submission on the client side
  2. On retry, first check whether the id already exists (store.get/lookup) and resume that request instead of resubmitting
  3. Catch the ValueError and return an idempotent 'duplicate request' response to the client rather than crashing the handler
  4. Ensure terminal requests are cleaned up from the store so ids can be safely reused if ids are scoped per session

Example fix

# before
store.submit(request_id)  # ValueError on retry

# after
import uuid
request_id = str(uuid.uuid4())  # fresh id per submission
store.submit(request_id)
Defensive patterns

Strategy: validation

Validate before calling

import uuid
request_id = str(uuid.uuid4())
try:
    record = store.submit(request_id)
except ValueError:
    # id collision: resume or regenerate
    record = store.submit(str(uuid.uuid4()))

Try / catch

try:
    store.submit(request_id)
except ValueError as e:
    if "Duplicate request_id" in str(e):
        return existing_response_or_conflict(request_id)
    raise

Prevention

When it happens

Trigger: Calling submit(request_id) twice without the first request reaching a terminal state and being removed — e.g. a client retrying a request with the same id, or two concurrent client requests arriving with colliding ids at _handle_client_request.

Common situations: Client-side retries (timeout + retry with the same id), id generation based on non-unique input (hash of prompt), reconnections replaying queued requests, or a bug where the same frame is handled twice.

Related errors


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