{"record":{"id":"c8d0fd5368196af9","repo":"openai/openai-python","slug":"stream-has-not-been-started-yet","errorCode":null,"errorMessage":"Stream has not been started yet","messagePattern":"Stream has not been started yet","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/openai/lib/streaming/_assistants.py","lineNumber":406,"sourceCode":"            if self._current_tool_call:\n                self.on_tool_call_done(self._current_tool_call)\n\n            self.on_run_step_done(event.data)\n            self.__current_run_step_id = None\n        elif event.event == \"thread.created\" or event.event == \"thread.message.in_progress\" or event.event == \"error\":\n            # currently no special handling\n            ...\n        else:\n            # we only want to error at build-time\n            if TYPE_CHECKING:  # type: ignore[unreachable]\n                assert_never(event)\n\n        self._current_event = None\n\n    def __stream__(self) -> Iterator[AssistantStreamEvent]:\n        stream = self.__stream\n        if not stream:\n            raise RuntimeError(\"Stream has not been started yet\")\n\n        try:\n            for event in stream:\n                self._emit_sse_event(event)\n\n                yield event\n        except _timeout_exceptions() as exc:\n            self.on_timeout()\n            self.on_exception(exc)\n            raise\n        except Exception as exc:\n            self.on_exception(exc)\n            raise\n        finally:\n            self.on_end()\n\n\nAssistantEventHandlerT = TypeVar(\"AssistantEventHandlerT\", bound=AssistantEventHandler)","sourceCodeStart":388,"sourceCodeEnd":424,"githubUrl":"https://github.com/openai/openai-python/blob/9917c6e28e66e90e1227b3d223c06a8c5441515a/src/openai/lib/streaming/_assistants.py#L388-L424","documentation":"Thrown by AssistantEventHandler.__stream__ when the internal generator is advanced before the handler has been bound to a real Stream via _init. __init__ eagerly creates self._iterator = self.__stream__(), but the generator body only runs on first next(); if iteration happens outside a with client...stream(...) block (which calls __enter__ -> _init), self.__stream is still None.","triggerScenarios":"Manually iterating handler.text_deltas or the handler itself without entering the stream context: next(handler) or for delta in handler.text_deltas before with client.beta.threads.runs.stream(..., event_handler=handler) has run. Also instantiating the handler and calling until_done() directly.","commonSituations":"Calling list(handler.text_deltas) to pre-collect output; refactoring away the with-block; misunderstandings about when the stream starts; sharing handler-created iterators across contexts.","solutions":["Always consume events/deltas inside the with (or async with) block returned by client.beta.threads.runs.stream / create_and_stream","Do not call next() on handler or its text_deltas iterator before entering the context","If you need the deltas, iterate stream.text_deltas on the stream object returned by the context manager, not on a bare handler"],"exampleFix":"# before\nhandler = MyHandler()\ndeltas = list(handler.text_deltas)  # stream not started\n\n# after\nwith client.beta.threads.runs.stream(..., event_handler=handler) as stream:\n    for delta in stream.text_deltas:\n        print(delta, end=\"\")","handlingStrategy":"validation","validationCode":"def ensure_started(handler) -> None:\n    if getattr(handler, \"_AssistantEventHandler__stream\", None) is None:\n        raise RuntimeError(\"enter the stream context before iterating\")","typeGuard":"def handler_is_live(h) -> bool:\n    return getattr(h, \"_AssistantEventHandler__stream\", None) is not None","tryCatchPattern":"try:\n    for delta in handler.text_deltas:\n        ...\nexcept RuntimeError as e:\n    if \"not been started\" in str(e):\n        # use the context-managed stream instead\n        ...","preventionTips":["Only iterate inside the with block","Prefer stream.text_deltas over handler.text_deltas","Never call next() on a bare handler"],"tags":["assistants","streaming","context-manager","iteration-order","python"],"backgroundTag":"iterating-before-stream-start","analyzedSha":"9917c6e28e66e90e1227b3d223c06a8c5441515a","analyzedAt":"2026-08-28T11:46:34.183Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}