sgl-project/sglang · error · InternalError

Encoder request was released: {state.req_id}

Error message

Encoder request was released: {state.req_id}

What it means

send_to_destination checks under the request's lifecycle lock that the ReqState is still the live entry in req_states and has not been release-requested; if the request was concurrently released, it raises InternalError to prevent sending an embedding whose buffers may be recycled.

Source

Thrown at python/sglang/srt/disaggregation/encoder/server.py:680

            )
        state.embedding_data = mm_data
        state.embedding_ready.set()

    async def _wait_for_embedding(self, state: ReqState) -> EmbeddingData:
        await state.embedding_ready.wait()
        if state.embedding_data is None:
            raise InternalError(f"No embedding available for request: {state.req_id}")
        return state.embedding_data

    async def send_to_destination(
        self, state: ReqState, destination: SendDestination
    ) -> None:
        async with state.lifecycle_condition:
            if (
                self.req_states.get(state.req_id) is not state
                or state.release_requested
            ):
                raise InternalError(f"Encoder request was released: {state.req_id}")
            state.active_sends += 1
        try:
            await self.delivery.send(state, destination)
        finally:
            async with state.lifecycle_condition:
                state.active_sends -= 1
                state.lifecycle_condition.notify_all()

    async def release_request(
        self, req_id: str, *, preserve_metadata: bool = False
    ) -> None:
        """Release backend resources, then the embedding, through one path."""
        state = self.req_states.get(req_id)
        if state is None:
            if not preserve_metadata:
                await meta_registry.discard(req_id)
            return
        async with state.lifecycle_condition:

View on GitHub (pinned to 0132848349)

Solutions

  1. Ensure only one component owns release for a request; do not manually release while sends are pending
  2. Tune request TTL / sweep interval so sends complete before release
  3. Retry the whole request with a fresh req_id if the send was aborted mid-flight
  4. Check logs for what triggered the concurrent release (timeout vs abort vs sweep)
Defensive patterns

Strategy: try-catch

Validate before calling

if encoder.req_states.get(req_id) is not state or state.release_requested:
    abort_send(req_id)

Try / catch

try:
    await encoder.send_to_destination(state, dest)
except InternalError as e:
    if 'released' in str(e):
        return  # request lifecycle ended; nothing to deliver
    raise

Prevention

When it happens

Trigger: A release_request (timeout, client abort, or sweep) racing with an in-flight send; calling send/send_with_url/run for a req_id that was already released by another coroutine or the periodic sweep.

Common situations: Client timeout triggering release while a slow transfer is queued; duplicate lifecycle management where two owners both release; long-running sends outliving the request TTL.

Related errors


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