vllm-project/vllm · error · ValueError

Lock must be provided for readers.

Error message

Lock must be provided for readers.

What it means

ShmObjectStorage requires a reader_lock for any instance constructed with is_writer=False. Readers must coordinate increments of the per-buffer in-use flag via a cross-process lock; without it the constructor refuses to build a half-initialized reader.

Source

Thrown at vllm/distributed/device_communicators/shm_object_storage.py:492

        self.max_object_size = max_object_size
        self.n_readers = n_readers
        self.serde_class = serde_class
        self.ser_de = serde_class()
        self.ring_buffer = ring_buffer
        self.is_writer = self.ring_buffer.is_writer

        self.flag_bytes = 4  # for in-use flag

        if self.is_writer:
            # Key-value mapping: key -> (address, monotonic_id)
            self.key_index: dict[str, tuple[int, int]] = {}
            # Reverse mapping: monotonic_id -> key
            self.id_index: dict[int, str] = {}
            # Writer flag to track in-use status: monotonic_id -> count
            self.writer_flag: dict[int, int] = {}
        else:
            if reader_lock is None:
                raise ValueError("Lock must be provided for readers.")

        self._reader_lock = reader_lock

    def clear(self) -> None:
        """Clear the object storage."""
        if self.is_writer:
            self.ring_buffer.clear()
            self.key_index.clear()
            self.id_index.clear()
            self.writer_flag.clear()
            logger.debug("Object storage cleared and reinitialized.")

    def copy_to_buffer(
        self,
        data: bytes | list[bytes],
        data_bytes: int,
        metadata: bytes,
        md_bytes: int,

View on GitHub (pinned to c794754062)

Solutions

  1. Pass the lock from the handle: ShmObjectStorage(..., reader_lock=handle.reader_lock)
  2. If spawning readers via pickle/spawn and the lock cannot cross the boundary, create the lock in the reader process from the same shm/semaphore name rather than passing None
  3. Check is_writer is set correctly — writer instances legitimately pass reader_lock=None

Example fix

# before
storage = ShmObjectStorage(..., is_writer=False, reader_lock=None)
# ValueError: Lock must be provided for readers.

# after
storage = ShmObjectStorage(..., is_writer=False, reader_lock=handle.reader_lock)
Defensive patterns

Strategy: validation

Validate before calling

# when building a reader from a handle
if not handle_is_writer:
    assert handle.reader_lock is not None, "reader_lock missing from handle"

Type guard

def is_valid_reader_config(is_writer: bool, reader_lock) -> bool:
    return is_writer or reader_lock is not None

Prevention

When it happens

Trigger: Instantiating ShmObjectStorage(..., is_writer=False, reader_lock=None) — e.g. building a reader from a handle but forgetting to pass the lock stored in ShmObjectStorageHandle.reader_lock.

Common situations: Custom code creating reader-side storage from a serialized handle (the handle carries reader_lock; developers drop it when the lock type is not picklable across their spawn method); refactors that changed the constructor signature to make the lock mandatory.

Related errors


AI-assisted analysis of vllm-project/vllm@c794754062 (2026-08-14). Data as JSON: /api/errors/af51989e35810e3b. Report an issue: GitHub.