{"record":{"id":"a3a4a238a4b53b65","repo":"microsoft/qlib","slug":"dataqueue-can-not-activate-twice","errorCode":null,"errorMessage":"DataQueue can not activate twice.","messagePattern":"DataQueue can not activate twice\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"qlib/rl/utils/data_queue.py","lineNumber":140,"sourceCode":"            try:\n                return self._queue.get(block=block, timeout=timeout)\n            except Empty:\n                if self._done.value:\n                    raise StopIteration  # pylint: disable=raise-missing-from\n\n    def put(self, obj: Any, block: bool = True, timeout: int | None = None) -> None:\n        self._queue.put(obj, block=block, timeout=timeout)\n\n    def mark_as_done(self) -> None:\n        with self._done.get_lock():\n            self._done.value = 1\n\n    def done(self) -> int:\n        return self._done.value\n\n    def activate(self) -> DataQueue:\n        if self._activated:\n            raise ValueError(\"DataQueue can not activate twice.\")\n        thread = threading.Thread(target=self._producer, daemon=True)\n        thread.start()\n        self._activated = True\n        return self\n\n    def __del__(self) -> None:\n        _logger.debug(f\"__del__ of {__name__}.DataQueue\")\n        self.cleanup()\n\n    def __iter__(self) -> Generator[Any, None, None]:\n        if not self._activated:\n            raise ValueError(\n                \"Need to call activate() to launch a daemon worker \"\n                \"to produce data into data queue before using it. \"\n                \"You probably have forgotten to use the DataQueue in a with block.\",\n            )\n        return self._consumer()\n","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/rl/utils/data_queue.py#L122-L158","documentation":"ValueError from `DataQueue.activate` (qlib/rl/utils/data_queue.py:140). A DataQueue launches exactly one daemon producer thread on first activation; `activate` is guarded by the `_activated` flag and refuses a second call. In normal usage the `with` block (`__enter__`) activates it, so manual activation plus a with-block causes the double fire.","triggerScenarios":"Calling `queue.activate()` explicitly and then entering `with queue:` (which calls activate again); or a custom lifecycle manager that activates the queue on setup and again on start.","commonSituations":"Integrating DataQueue into a custom training loop where activation was already handled by a wrapper; copy-pasted setup code that activates 'for safety'; reusing one DataQueue object across two training runs without recreating it.","solutions":["Drop the manual `activate()` call and rely on the with-block: `with DataQueue(...) as q: for item in q: ...`.","If managing lifecycle manually, check `q._activated` semantics via the public contract: activate once, and create a new DataQueue instance for each run.","Restructure code so there is exactly one owner of activation (either the context manager or your code, never both)."],"exampleFix":"// before\nq = DataQueue(gen).activate()\nwith q:  # __enter__ activates again -> ValueError\n    for x in q: ...\n// after\nwith DataQueue(gen) as q:  # single automatic activation\n    for x in q: ...","handlingStrategy":"validation","validationCode":"def start_queue(q):\n    if getattr(q, \"_activated\", False):\n        raise RuntimeError(\"DataQueue already activated; create a new instance per run\")\n    return q.activate()","typeGuard":"def queue_is_activated(q) -> bool:\n    return bool(getattr(q, \"_activated\", False))","tryCatchPattern":"try:\n    with DataQueue(gen) as q:\n        pass\nexcept ValueError as e:\n    if \"activate twice\" in str(e):\n        q = DataQueue(gen)  # fresh instance, single activation\n    else:\n        raise","preventionTips":["Never call activate() manually when using the with-block; the context manager owns activation.","Create a new DataQueue for each training run or epoch.","Keep exactly one lifecycle owner for the queue in your codebase."],"tags":["rl","data-queue","lifecycle","context-manager","double-activation"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}