Repository navigation
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
♻️ Reproduction Steps
- Use copilokit (npm 1.51.2) with react (19.2.4) nextjs (16.1.6) and openai provider
- Use CopilotSidebar and useCoAgent (send initial state to agent)
- Use Copilotkit (python pkg version 0.1.74)
sample code (real code):
async def orchestrator_node(state: WorkflowState, config: Optional[RunnableConfig] = None):
await copilotkit_emit_message(config, "Routing...")
config_internal = copilotkit_customize_config(config, emit_messages=False)
model = ChatOpenAI(model="gpt-4o")
prompt = "Randomly return one of words: left_intent, right_intent."
response = await model.ainvoke(prompt, config_internal)
if response.content == "right_intent":
return Command(
goto="right_node",
update={
"messages": state.get("messages", []),
"intent": response.content,
}
)
else:
return Command(
goto="left_node",
update={
"messages": state.get("messages", []),
"intent": response.content,
}
)
async def left_node(state: WorkflowState, config: Optional[RunnableConfig] = None):
config_internal = copilotkit_customize_config(config, emit_messages=True)
model = ChatOpenAI(model="gpt-4o")
prompt = "Provide a point for the left-wing political spectrum."
response = await model.ainvoke(prompt, config_internal)
await copilotkit_exit(config_internal)
return Command(
goto=END,
update={
"messages": state.get('messages', []) + [response]
}
)
async def right_node(state: WorkflowState, config: Optional[RunnableConfig] = None):
config_internal = copilotkit_customize_config(config, emit_messages=True)
model = ChatOpenAI(model="gpt-4o")
prompt = "Provide a point for the right-wing political spectrum."
response = await model.ainvoke(prompt, config_internal)
await copilotkit_exit(config_internal)
return Command(
goto=END,
update={
"messages": state.get('messages', []) + [response]
}
)
✅ Expected Behavior
When a message is sent through the interface to the Langraph agent, which has an orchestrator node with LLM calls, the chatbot should send a response and successfully end the conversation.
❌ Actual Behavior
When sending a message on the frontend to the Langraph agent, which has an orchestrator node as a decision node with LLM calling, and also terminal nodes with LLM calling, the chatbot does not return any response (although the agent terminates successfully), and the following error occurs on the screen: “Run ended without emitting a terminal event”.
𝌚 CopilotKit Version
├── @copilotkit/[email protected] -> .\node_modules\.pnpm\@[email protected]_5970c78ec49eb4bdbc956ab13472663d\node_modules\@copilotkit\react-core
├── @copilotkit/[email protected] -> .\node_modules\.pnpm\@[email protected]_fef36c02d045e1dd60c7e752d719a54d\node_modules\@copilotkit\react-ui
├── @copilotkit/[email protected] -> .\node_modules\.pnpm\@[email protected]__e463dd38407bd967fd5cd527e0ad5e09\node_modules\@copilotkit\runtime📄 Logs (Optional)
Copilotkit Web Inspector (dev console):
Latest "AG-UI Events":
{
"type": "RUN_ERROR",
"message": "Run ended without emitting a terminal event",
"code": "INCOMPLETE_STREAM"
}
Frontend console error:
"Agent execution failed: Error: Cannot send 'TEXT_MESSAGE_END' event: No active text message found with ID 'lc_run-- [uuid]'. A 'TEXT_MESSAGE_START' event must be sent first. at Observable.init [as _subscribe]Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working
Activity
copilotkit-support-bot commentedon Feb 13, 2026
Guidance from the codebase addresses the INCOMPLETE_STREAM error with LangGraph orchestrator nodes, outlining likely causes and step-by-step resolutions. See the detailed answer below for exact instructions and code snippets.
Details
The error you're encountering,
INCOMPLETE_STREAM("Run ended without emitting a terminal event") and the subsequent "No active text message found" error, typically occurs when a LangGraph node uses a customized configuration (viacopilotkit_customize_config) that suppresses message emission, but the overall run lifecycle fails to signal completion correctly to the CopilotKit runtime.2-3 Likely Causes Investigated:
emit_messages=Falseis used, the runtime filters outTextMessageStartbut might still attempt to send aTextMessageEndif the metadata is not consistently propagated to the final "stop" chunk of the LLM stream.LangGraphAgentimplementation (especially in older versions like0.1.74) may not be yielding a proper terminal event (RUN_FINISHED) that the TypeScript runtime expects to close the stream gracefully.copilotkit_emit_messageimmediately before an LLM call withemit_messages=Falsecan sometimes lead to state overlap in the event source accumulator if the manual message is not fully processed before the LLM stream starts.Solution & Recommended Steps
To resolve this, ensure that your LangGraph nodes follow the updated pattern for terminal nodes and that you are using consistent configuration across nodes:
Ensure Terminal Node Signaling: Instead of relying solely on
copilotkit_exit, ensure your terminal nodes return the final state correctly. If you are using an orchestrator that routes to sub-nodes, make sure the sub-nodes (likeleft_nodeandright_node) are recognized as terminal by LangGraph (e.g., routing toEND).Fix
copilotkit_customize_configusage: Ensure theconfigpassed tocopilotkit_customize_configis the "clean" base config. Avoid nesting customized configs.Update CopilotKit Python SDK: There were significant improvements in event streaming and terminal event handling in later versions. It is highly recommended to upgrade to the latest version of the Python SDK:
Explicitly handle the final state in your nodes:
Ensure that when you call
copilotkit_exit, it is the final action in a terminal node. Note thatcopilotkit_exitdoesn't stop execution immediately; it sets a flag for the next sync event.Why the error occurs:
The
INCOMPLETE_STREAMerror specifically means the CopilotKit Runtime reached the end of the HTTP stream from your Python backend but never saw an event of typeRunFinished. TheTEXT_MESSAGE_ENDerror occurs because the runner tries to "cleanup" and close any open messages when the stream ends abruptly, but sinceemit_messages=Falseprevented the start of the message, the cleanup fails.Documentation & Examples:
Confidence Level: High (This is a known behavior in older SDK versions when mixing manual emissions with suppressed LLM streams).
Was this helpful?
If this solution worked for you, please click on the appropriate option below to help us improve:
✅ This was helpful | ❌ Need more help
fix(runtime): clean up stale messagesInProcess when copilotkit:emit-m…