#Langgraph Interrupt never resolves via CopilotKit

1 messages · Page 1 of 1 (latest)

twin islandBOT
#

This solution has been AI generated

Your interrupt UI renders, but the graph never resumes. This usually means the resolution isn’t being sent back to the exact interrupt event/thread, or the resolve callback is lost on re-render. Ensure you resolve the current interrupt event in the same thread, and that the agent is streaming events.

What to verify

  • Resolve is called immediately with a string from the submit handler.
  • Keep handler stable to avoid stale closures on re-render.
  • The agent is running and streaming events; interrupts are only processed when events flow.
  • Thread consistency: the same threadId used by useAgent is the one the interrupt belongs to.

Minimal working pattern

// Stable submit handler and controlled input
function InterruptForm() {
  const [response, setResponse] = useState("");
  useLangGraphInterrupt({
    render: ({ event, resolve }) => (
      <form
        onSubmit={(e) => {
          e.preventDefault();
          resolve(response); // send the value to resume the graph
        }}
      >
        <p>{event.value}</p>
        <input value={response} onChange={(e) => setResponse(e.target.value)} />
        <button type="submit">Submit</button>
      </form>
    ),
  });
  return null;
}

Ensure event streaming and thread alignment

const { agent, threadId } = useAgent({ agentId: "agent" });
// Subscribe so interrupts are delivered
useEffect(() => {
  const unsub = agent.subscribe(() => {});
  return unsub;
}, [agent]);
// Start/run the graph so events flow
// agent.run({...}) or your existing trigger that produced the interrupt

Alternative hook API (from codebase example)

const { resolveInterrupt } = useLangGraphInterrupt();
<form onSubmit={(e)=>{ e.preventDefault(); resolveInterrupt(response); }}>
  ...
#

</form>


If the form still re-renders without resuming, it’s almost always a thread/event mismatch. Make sure the component handling the interrupt is mounted within the same provider tree and uses the same `agent`/`threadId` as the run that raised the interrupt.


**Was this helpful?**

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

Thank you for your feedback! Our team will provide additional assistance. 🔄

winter girder
#

This used to work on CopilotKit 1.10, the issue is happening on 1.50

winter girder
#

Adding some analysis:

const { agent } = useAgent({
    agentId: "agent",
  });

  console.log("useAgent threadId", agent.threadId);

  useLangGraphInterrupt({
    render: ({ event, resolve }) => {

      console.log("Thread ID in interrupt", agent.threadId);
      return (
        <div>
          <p>{event.value}</p>
          <form
            onSubmit={(e) => {
              e.preventDefault();
              console.log(
                "onSubmit",
                (e.target as HTMLFormElement).response.value
              );
              resolve(
                "Resolving with: " +
                  (e.target as HTMLFormElement).response.value
              );
            }}
          >
            <input
              type="text"
              name="response"
              placeholder="Enter your response"
            />
            <button type="submit">Submit</button>
          </form>
        </div>
      );
    },
  });

Inspecting the threadId shows the following in the logs:

useAgent threadId 61a62ac3-eeef-4a39-abd7-259fd2212abd
useAgent threadId b06a7ae4-4fb7-49fc-b428-644554384cc4
useAgent threadId 61870927-e24f-4fec-8cf6-eaba1c2cc758
useAgent threadId a4350ac6-eea7-4033-bc9c-abd2b7ba9a5a
useAgent threadId ddb8328e-a3cc-47a2-a0da-26391315bf75

Then when the interrupt happens:

Thread ID in interrupt 61a62ac3-eeef-4a39-abd7-259fd2212abd


It seems that while the page is loading, a bunch of thread ids are created until CopilotKit converges on the last one ddb8328e-a3cc-47a2-a0da-26391315bf75 however the hooks from CopilotKit are initialized with the first threadId 61a62ac3-eeef-4a39-abd7-259fd2212abd. I assume this is the reason for the issue.

Is this a bug?

winter girder
#

If I switch to using useCoAgent instead of useAgent, useLangGraphInterrup works fine

white stump
#

@rough flicker @kindred warren @round fable ? is this another bug ? if not, please provide a working example for langgraph interrupts with useLanggraphInterrupt in v2 ! same as OP this broke for me when going from 1.1 to 1.5

lean walrus
white stump
#

the langgraph interrupt response in browwser console:
data: {"type":"CUSTOM","rawEvent":{"value":"hello interrupting here for a second","id":"935aabc015542f32fd6668ef6cd10e70"},"name":"on_interrupt","value":"hello interrupting here for a second"}
but copilotkit ignroes it