{"record":{"id":"620bc4ea6f2ca8f4","repo":"langchain-ai/langgraph","slug":"atee-requires-n-1","errorCode":null,"errorMessage":"atee() requires n >= 1","messagePattern":"atee\\(\\) requires n >= 1","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/langgraph/langgraph/stream/stream_channel.py","lineNumber":309,"sourceCode":"        Caller-driven fan-out: each branch's `__anext__` either pops\n        from its own buffer or, under a shared `asyncio.Lock`, pulls\n        one item from the underlying cursor and distributes it to\n        every branch's buffer.\n\n        Args:\n            n: Number of branches to create. Must be >= 1.\n\n        Returns:\n            A tuple of `n` async iterators over the same underlying\n            stream.\n\n        Raises:\n            TypeError: If the channel is unbound or bound to sync mode.\n            RuntimeError: If the channel already has a subscriber.\n            ValueError: If `n` < 1.\n        \"\"\"\n        if n < 1:\n            raise ValueError(\"atee() requires n >= 1\")\n        source = self.__aiter__()\n        buffers: list[deque[T]] = [deque() for _ in range(n)]\n        exhausted = [False]\n        error: list[BaseException | None] = [None]\n        lock = asyncio.Lock()\n\n        async def branch(i: int) -> AsyncIterator[T]:\n            buf = buffers[i]\n            while True:\n                if buf:\n                    yield buf.popleft()\n                    continue\n                if exhausted[0]:\n                    if error[0] is not None:\n                        raise error[0]\n                    return\n                async with lock:\n                    if buf or exhausted[0]:","sourceCodeStart":291,"sourceCodeEnd":327,"githubUrl":"https://github.com/langchain-ai/langgraph/blob/38031739e551638e373fb553453256c23feeb41f/libs/langgraph/langgraph/stream/stream_channel.py#L291-L327","documentation":"Guard clause at the top of StreamChannel.atee, the async fan-out helper. It validates the branch-count argument before creating any buffers or the shared asyncio.Lock: an n of 0 (or negative) would produce an empty tuple of iterators and silently detach the caller from the stream while the underlying cursor goes unconsumed, so it is rejected eagerly. The input at fault is the n parameter passed to atee(); the sync counterpart tee() enforces the same invariant.","triggerScenarios":"Thrown at libs/langgraph/langgraph/stream/stream_channel.py:309 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Pass n >= 1 to atee()","Use plain `async for` if only one consumer is needed"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"38031739e551638e373fb553453256c23feeb41f","analyzedAt":"2026-08-26T18:02:49.312Z","contentChangedAt":"2026-08-26T18:02:49.312Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}