How to clone a thread in LangGraph

Hi everyone!

I’m working with LangGraph using PostgreSQL as the checkpointer. I’m trying to implement functionality equivalent to copy_thread (the one available in the Server/threads API): create a new thread_id that is a full copy of the source thread, including state + checkpoint/history, and that can continue exactly where it left off (without restarting from the entrypoint).

I’ve tried the “supported” local approach of cloning only the state (snapshot.values) into a new thread_id using update_state, like this:

snapshot = graph.get_state({“configurable”: {“thread_id”: src, “checkpoint_id”: src_cp}})
new_cfg = graph.update_state({“configurable”: {“thread_id”: dst}}, snapshot.values)
result = graph.invoke(None, config=new_cfg)

However, my understanding is that this only copies values and does not copy the full checkpoint (history, next, internal tasks, parents, etc.), and in my case the graph may return to the entrypoint or fail to resume from the exact same point.

Question: Is there any supported/official way to perform a “real” copy_thread in local OSS (i.e., a new thread_id with checkpoints and history fully copied), or is this not supported by design?

Best regards

hi @aitor-sh-8994

I found this, may be useful Copy Thread - Docs by LangChain

We’re running LangGraph OSS inside our own FastAPI service (self-managed). The Copy Thread endpoint belongs to the official Agent Server runtime / API, which we’re not using. In local OSS we need to implement an equivalent ourselves.

I think there is neither an official nor an unofficial pattern for copying a thread. Or at least I don’t know of any.
But I believe it’s not rocket science. I see the tables in DB checkpoints, checkpoint_writes and checkpoint_blobs - all connected with thread_id column - so maybe it just a matter of copying the rows and changing thread_id value to sth else?