#RunError when trying to resolve Interrupt via Chat

1 messages · Page 1 of 1 (latest)

small valley
#

We have a langgraph interrupt with a custom UI which has actions like e.g. edit, accept, response. While this interrupt is shown in the Copilotchat, i can successfully resolve it with "edit" or "accept" actions. however, if i try to CHAT instead (see attached image), i get a RUN Error in FE. I would expect here that the framework handles this by resolving the interrupt with the "response" action. e.g:

{
    "type": "response",
            "args": "Please make the Meeting 2 hours long and one day later!"
}

how do i do that?

true sableBOT
#

This solution has been AI generated

You’re seeing RUN_ERROR (code: INCOMPLETE_STREAM) because the chat "Send" starts a new run while the LangGraph run is paused at an interrupt. To support typing a reply, intercept the chat submission and resolve the active interrupt with a "response" action instead of starting a new run.

Why this happens

When an interrupt is active, LangGraph waits for a resume. Sending a chat message triggers a new run, so the prior run never emits a terminal event, resulting in INCOMPLETE_STREAM.

Client-side fix: map chat input to the interrupt "response"

Use useLangGraphInterrupt to capture the current resolve and redirect CopilotChat's onSubmitMessage to it.

import React from "react";
import { useLangGraphInterrupt } from "@copilotkit/react-core";
import { CopilotChat } from "@copilotkit/react-ui";

export function MyChat() {
  const resolveRef = React.useRef<((v: any) => void) | null>(null);

  useLangGraphInterrupt({
    render: ({ event, resolve }) => {
      resolveRef.current = resolve;
      return (
        <div>
          <p>{event.value?.content}</p>
          <button onClick={() => resolve({ type: "accept" })}>Accept</button>
        </div>
      );
    },
    onCleanup: () => { resolveRef.current = null; }
  });

  return (
    <CopilotChat
      onSubmitMessage={async (message) => {
        if (resolveRef.current) {
          resolveRef.current({ type: "response", args: message });
          return; // prevent starting a new run while interrupted
        }
      }}
    />
  );
}

Agent-side handling (LangGraph)

Ensure your node expects the structured response and processes args.

#
def my_node(state):
    decision = interrupt("Provide edits or feedback")
    if isinstance(decision, dict) and decision.get("type") == "response":
        user_text = decision.get("args")
        # handle user_text

Notes

  • The default chat input is disabled during interrupts; if your custom UI enables it, you must reroute submissions to resolve.
  • This avoids starting a new run and cleanly resumes the suspended one.

Was this helpful?

If this solution worked for you, please click on the appropriate option below to help us improve:

small valley
#

found a solution for this ! i will post it here so others can maybe make use of it. we basically need to intercept chat messages during interrupts and transform them into forwardedProps: {commands: "..."}}

true sableBOT
#

Thanks @small valley for sharing the solution! This will definitely help others who run into the same thing.