Summary
Using --resume with MemorySaver sometimes re-runs the agent from scratch instead of resuming at the interrupt point, with no error message. The behavior is inconsistent and there is no documentation explaining why or how to fix it.
Root Cause
MemorySaver is an in-memory checkpointer. When the initial process exits (normally or due to an interrupt), all checkpoints are lost. When --resume is called in a new process, there are no checkpoints to restore from — so the runtime either starts a fresh run silently or fails in an opaque way.
Whether the runtime injects its own SQLite-backed checkpointer (and under what conditions) depends on the presence of --state-file, but this behavior is not documented anywhere.
Observed Behaviour
- Run agent:
uv run uipath run agent.py '{"invoices": [...]}'
- Agent hits
interrupt(), process suspends
- Human completes the Action Center task
- Run:
uv run uipath run agent.py --resume
- Result: agent starts from scratch (re-runs all tools) rather than resuming at the interrupt
No error is printed. The --resume flag appears to succeed but the checkpoint is not found.
Workaround
Always pass --state-file on both the initial run and every --resume:
# Initial run
uv run uipath run agent.py '{"invoices": [...]}' --state-file ./agent-state.db
# Resume
uv run uipath run agent.py --resume --state-file ./agent-state.db
When --state-file is provided, the runtime persists LangGraph checkpoints in a SQLite file that survives across process invocations.
Suggested Fix
- Print which checkpointer is active at startup (e.g.
INFO: Using SqliteCheckpointer (state-file: ./agent-state.db))
- Warn at startup if
MemorySaver is detected and --state-file is not provided:
Warning: MemorySaver is in-memory only. Cross-process --resume will silently fail.
Use --state-file to persist checkpoints across process invocations.
- Document the
--state-file requirement prominently in the HITL/interrupt docs.
Impact
- Severity: Medium
- Affects all LangGraph agents using
interrupt() + MemorySaver for local development
- The silent failure mode causes developers to waste significant time debugging why resume doesn't work
Summary
Using
--resumewithMemorySaversometimes re-runs the agent from scratch instead of resuming at the interrupt point, with no error message. The behavior is inconsistent and there is no documentation explaining why or how to fix it.Root Cause
MemorySaveris an in-memory checkpointer. When the initial process exits (normally or due to an interrupt), all checkpoints are lost. When--resumeis called in a new process, there are no checkpoints to restore from — so the runtime either starts a fresh run silently or fails in an opaque way.Whether the runtime injects its own SQLite-backed checkpointer (and under what conditions) depends on the presence of
--state-file, but this behavior is not documented anywhere.Observed Behaviour
uv run uipath run agent.py '{"invoices": [...]}'interrupt(), process suspendsuv run uipath run agent.py --resumeNo error is printed. The
--resumeflag appears to succeed but the checkpoint is not found.Workaround
Always pass
--state-fileon both the initial run and every--resume:When
--state-fileis provided, the runtime persists LangGraph checkpoints in a SQLite file that survives across process invocations.Suggested Fix
INFO: Using SqliteCheckpointer (state-file: ./agent-state.db))MemorySaveris detected and--state-fileis not provided:--state-filerequirement prominently in the HITL/interrupt docs.Impact
interrupt()+MemorySaverfor local development