Skip to content

🐛 Bug: error INCOMPLETE_STREAM in langgraph agent (with orchestrator node) #3208

Closed

Description

@jcguimaraesnet

♻️ Reproduction Steps

  1. Use copilokit (npm 1.51.2) with react (19.2.4) nextjs (16.1.6) and openai provider
  2. Use CopilotSidebar and useCoAgent (send initial state to agent)
  3. 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]

Activity

  1. copilotkit-support-bot commented on Feb 13, 2026

    @copilotkit-support-bot

    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 (via copilotkit_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:

    1. Inconsistent Message Emission: When emit_messages=False is used, the runtime filters out TextMessageStart but might still attempt to send a TextMessageEnd if the metadata is not consistently propagated to the final "stop" chunk of the LLM stream.
    2. Missing Terminal Event: The Python LangGraphAgent implementation (especially in older versions like 0.1.74) may not be yielding a proper terminal event (RUN_FINISHED) that the TypeScript runtime expects to close the stream gracefully.
    3. Manual Message Interference: Using copilotkit_emit_message immediately before an LLM call with emit_messages=False can 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 (like left_node and right_node) are recognized as terminal by LangGraph (e.g., routing to END).

    • Fix copilotkit_customize_config usage: Ensure the config passed to copilotkit_customize_config is 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:

      pip install copilotkit --upgrade
    • 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 that copilotkit_exit doesn't stop execution immediately; it sets a flag for the next sync event.

    async def left_node(state: WorkflowState, config: Optional[RunnableConfig] = None):
        # Ensure we use the base config for customization
        config_internal = copilotkit_customize_config(config, emit_messages=True)
        model = ChatOpenAI(model="gpt-4o")
        prompt = "Provide a point for the left-wing political spectrum."
        
        # Use config_internal for the LLM call
        response = await model.ainvoke(prompt, config=config_internal)
        
        # Signal exit on the internal config
        await copilotkit_exit(config_internal)
    
        return {
            "messages": state.get('messages', []) + [response]
        }

    Why the error occurs:

    The INCOMPLETE_STREAM error specifically means the CopilotKit Runtime reached the end of the HTTP stream from your Python backend but never saw an event of type RunFinished. The TEXT_MESSAGE_END error occurs because the runner tries to "cleanup" and close any open messages when the stream ends abruptly, but since emit_messages=False prevented 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

  2. added a commit that references this issue on Mar 6, 2026
    5884dde
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions