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
- Pass the lock from the handle: ShmObjectStorage(..., reader_lock=handle.reader_lock)
- 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
- 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
- Always transport ShmObjectStorageHandle as a whole (it carries reader_lock)
- Construct readers via the provided handle/from_handle API instead of manual kwargs
- Add a constructor unit test covering reader-without-lock
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
- PostGradPassManager can not be kept in CompilationConfig.
- Only readers can dequeue
- Key '{key}' already exists in the storage.
- ec_transfer_config must be set for ECConnectorBase
- ec_transfer_config must be set for ECConnectorBase
AI-assisted analysis of vllm-project/vllm@c794754062 (2026-08-14).
Data as JSON: /api/errors/af51989e35810e3b.
Report an issue: GitHub.