{"record":{"id":"d491dd689ab6411c","repo":"vllm-project/vllm","slug":"data-for-address-id-address-monotonic-id-has","errorCode":null,"errorMessage":"Data for address:id '{address}:{monotonic_id}' has been modified or is invalid.","messagePattern":"Data for address:id '(.+?):(.+?)' has been modified or is invalid\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"vllm/distributed/device_communicators/shm_object_storage.py","lineNumber":618,"sourceCode":"        # Write data to buffer\n        with self.ring_buffer.access_buf(address) as (data_view, metadata):\n            data_view[: self.flag_bytes] = self.ring_buffer.int2byte(0)\n            self.copy_to_buffer(\n                object_data, data_bytes, object_metadata, md_bytes, data_view\n            )\n        self.increment_writer_flag(monotonic_id)\n\n        # Update key index\n        self.key_index[key] = (address, monotonic_id)\n        self.id_index[monotonic_id] = key\n        return address, monotonic_id\n\n    def get(self, address: int, monotonic_id: int) -> Any:\n        # Read data from buffer\n        with self.ring_buffer.access_buf(address) as (data_view, buf_metadata):\n            # check id from metadata\n            if buf_metadata[0] != monotonic_id:\n                raise ValueError(\n                    f\"Data for address:id '{address}:{monotonic_id}'\"\n                    \" has been modified or is invalid.\"\n                )\n\n            obj = self.ser_de.deserialize(data_view[self.flag_bytes :])\n\n            # decrease the in-use flag for reader reads\n            if self._reader_lock is not None:\n                with self._reader_lock:\n                    self.increment_reader_flag(data_view[: self.flag_bytes])\n            else:\n                # if self._reader_lock is None, it means we are the writer\n                # in this case, we do not need to decrease the reader count\n                assert self.is_writer\n\n        return obj\n\n    def touch(","sourceCodeStart":600,"sourceCodeEnd":636,"githubUrl":"https://github.com/vllm-project/vllm/blob/c794754062d49a8fdb63ab3c5215b488b865030c/vllm/distributed/device_communicators/shm_object_storage.py#L600-L636","documentation":"ShmObjectStorage.get(address, monotonic_id) validates the monotonic id stored in the buffer's metadata before deserializing. A mismatch means the slot at that address has been reallocated (the old object was freed and a newer object with a higher monotonic id now lives there), or the address/id pair is stale/corrupt. Reading further would return another object's data, so it raises.","triggerScenarios":"Holding an (address, id) pair across a free_unused()/ring-buffer wraparound and then calling get(); using a key_index entry from before the storage was cleared; readers lagging behind while the writer aggressively recycles buffer space.","commonSituations":"Readers falling behind under memory pressure so buffers get reclaimed (MemoryError-driven free_unused() on the writer); a crash+restart of the writer clearing storage while readers keep old handles; races where consumption outlives retention.","solutions":["Treat the ValueError as a cache miss: re-fetch the object by key from a current key_index lookup (or the producer) instead of reusing a stale address:id pair","Keep readers from lagging: consume objects promptly so in-use flags keep buffers from being freed","Re-lookup the key before every get(): address, mid = storage.key_index[key]"],"exampleFix":"# before\nobj = storage.get(address, monotonic_id)  # stale after wraparound\n\n# after\naddress, monotonic_id = storage.key_index[key]  # refresh pair\ntry:\n    obj = storage.get(address, monotonic_id)\nexcept ValueError:\n    obj = recompute_or_refetch(key)  # slot was recycled","handlingStrategy":"try-catch","validationCode":"address, mid = storage.key_index[key]  # always re-resolve fresh pairs\n# verify liveness before the expensive read if API exposes it","typeGuard":null,"tryCatchPattern":"try:\n    obj = storage.get(address, mid)\nexcept ValueError as e:\n    if \"modified or is invalid\" in str(e):\n        obj = refetch_from_producer(key)  # treat as eviction\n    else:\n        raise","preventionTips":["Never cache (address, monotonic_id) pairs across consumer pauses; re-resolve from key_index","Keep readers fast enough that buffers are not reclaimed under them","After writer restarts/clears, discard all cached key handles"],"tags":["shared-memory","stale-handle","race-condition"],"backgroundTag":null,"analyzedSha":"c794754062d49a8fdb63ab3c5215b488b865030c","analyzedAt":"2026-08-14T21:17:39.825Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}