Last week was about approvals. This week is about what happens after one: the resume. Your agent pauses, a human clicks yes, the run picks up from a checkpoint, and somewhere in there your charge, email or webhook can fire twice. The final state looks fine. Your payment dashboard doesn't.
The theme this week: side effects on resume and checkpointing. All five releases below touch it.
Top 5 that matter
1. LangGraph 1.2.16 (Oct 16)
What shipped: Four resume fixes, per the release notes. A subgraph no longer reruns its finished tasks on resume (#9315). A resumed exit run saves its pending writes once (#9314). A resumed Command's update is applied once (#9322). Other tasks now finish when a resume value is invalid (#9265). Why care: In our own fixture (parallel approvals inside a subgraph, answered one at a time), three approvals made six charges on 1.2.15 and three on 1.2.16, and the final graph state looked correct both times. Upgrade. Then read "Skip the hype" below. Release notes
2. langgraph-checkpoint-postgres 3.2.0 (Oct 14)
What shipped: prune now works on PostgresSaver and AsyncPostgresSaver. Before, both inherited a base method that raised NotImplementedError. Two strategies: delete drops every checkpoint, write and blob of the given threads in one transaction; keep_latest keeps each namespace's latest checkpoint with its pending writes and deletes the rest. Each thread is pruned on one REPEATABLE READ snapshot, so a run writing to the thread at the same time is safe. Why care: Long-lived threads finally have a supported way to stop growing forever. One catch: keep_latest refuses threads that use a DeltaChannel and prunes nothing, because that channel rebuilds its value from older checkpoints. Release notes · PR #9290
3. Mastra core 1.76 to 1.78 (Oct 13 to Oct 16)
What shipped: Durable agent runs are now claimed by the execution driving them. Storage adapters enforce "run fences," so an execution that lost ownership, say after crash recovery, can't overwrite the recovered run's state (1.76, extended to more adapters in 1.77). In 1.78, resume keeps suspendData after a crash, and invalid resume data throws AGENT_RESUME_INVALID_DATA without consuming the suspended run. Why care: Two workers on one run is how resumes go wrong in production. Fencing makes the loser's writes bounce instead of silently stomping the winner's. And a bad resume payload no longer burns your only chance to resume. 1.76.0 notes · 1.78.0 notes
4. Pydantic AI v2.57.0 (Oct 15)
What shipped: A Harness ApprovalReviewer. A second model looks at each tool call that needs approval and answers one risk question. "No risk" approves the call on the person's behalf. "Yes," "unsure," or a model failure leaves it for the person, the same as without the reviewer. It never denies a call and never runs one itself. Also: waits between continuation polls are now durable DBOS.sleep steps under DBOSDurability. Why care: It's the "auto-review" idea from coding agents, built into a framework. It cuts approval fatigue on harmless calls like ls. Just remember it only widens what runs without a human, so choose which tools it covers carefully. Release notes · PR #10143
5. Agno v3.1.4 (Oct 16)
What shipped: ClaudeAgent and CodexAgent take a sandbox= parameter and run inside an isolated per-session computer. Each turn claims the session through a lease row in Postgres, restores from the last committed checkpoint, runs, then captures and verifies a new checkpoint and publishes the run row and recovery point in one transaction. A cancelled or failed turn publishes nothing. v3.1.5 (Oct 19) adds S3CheckpointStore so several replicas can share checkpoints. Why care: This is the shape you want for any resumable agent: lease, restore, run, commit atomically. A half-finished turn can't become the state you resume from. v3.1.4 notes · v3.1.5 notes
Try this
Stop the double charge on LangGraph resume (re-tested on 1.2.16, Oct 19).
What it does. When a run resumes after interrupt(), LangGraph runs the paused node again from the top. The template shows the bug (a charge before interrupt() fires twice) and the fix: an approval node that only calls interrupt(), a separate execute node, and an idempotency key built from thread_id.
Setup (what we ran). This is a Pro template. The public page previews the first 30 lines (setup code and the naive graph); the fixed graph is in the Signal Pro pack. From the template folder:
printf 'langgraph==1.2.16\nlanggraph-checkpoint==4.3.0\n' > requirements.txt
python3 -m venv .venv && .venv/bin/pip install -q -r requirements.txt
.venv/bin/python idempotent_approval.py
On langgraph 1.2.16 (Python 3.12 and 3.13), the output matched the template's saved run 5 times out of 5. The naive graph charged once while paused and twice after resume. The fixed graph charged 0 times while paused, once after resume, and still once after we replayed execute from an earlier checkpoint.
Crash-test it.
.venv/bin/pip install -q "agentsignal-check[langgraph] @ git+https://github.com/agentsignal/[email protected]"
.venv/bin/agentsignal check --scan idempotent_approval.py
Result: exit 1 with one high finding, AS101: api.charge() runs before interrupt() in the naive node. That bug is there on purpose. The fixed graph isn't flagged. We also ran the full kill-and-restart crash test (agentsignal check --graph ... --effect ...): the fixed graph survived 5/5 crash tests and the naive graph survived 1/5, with the same result on every one of 5 runs on 1.2.16 and on 1.2.15.
What needed a workaround. - The template pins langgraph==1.2.15, so you have to edit the pin to get 1.2.16. Adding langgraph==1.2.16 next to the pinned file fails as unsatisfiable. - The full crash test doesn't plug into the template as shipped. Its graph builders take a payment API object instead of a checkpointer, and the fake payment ledger lives in memory. We wrapped it in a 20-line adapter; the template code itself was unchanged. - The tests need pytest, which isn't in requirements.txt.
Skip the hype
"Upgrade to 1.2.16 and you're safe." You're not. In our re-test on 1.2.16, a graph guarded only by an "already charged?" state check, with no idempotency key, still double-charged after a crash before the checkpoint, and again when the same approval was delivered twice. LangGraph doesn't promise a node runs exactly once, and there's an open issue asking the docs to say so (#9240). Upgrade, and key every side effect anyway.
Claude Code's point releases. Five this week, v2.1.299 to v2.1.303. The notable bit is idle compaction: a conversation over 200K tokens left idle for about 54 minutes gets compacted before its prompt cache expires. The rest is mods, vim motions and fixes. Update when it suits you. (v2.1.299 notes · v2.1.303 notes)
Pro subscribers get the full teardown of the LangGraph double charge: root cause, what to check in your own code, and the fix. Signal Pro is $7/mo or $69/yr.
That's the signal. Reply and tell me where a resume bit you.
— Mounir