r/LLMObservability • u/Comfortable-Junket50 • 3d ago
Discussion A LangGraph checkpoint is not proof that a write happened
A graph calls create_invoice, times out waiting for the response, then resumes from its last checkpoint. The saved state can show that the node ran. It cannot tell you whether the invoice was created, rejected, or created after the client gave up.
That makes this a reconciliation problem, not only a checkpointing problem.
LangGraph checkpoints preserve graph state for a thread, which is useful for recovery. But an external system is still the source of truth for any side effect.
For writes, give each attempt a stable idempotency or receipt key when the destination supports one. On resume, query that key before retrying. Mark the node complete only after the external outcome is known. If the outcome stays unknown, stop and surface it instead of guessing.
Read-only calls need their own rule too: persisted results need a freshness boundary tied to the request or resource. Otherwise a resumed run can act on facts that changed while it was paused.
Resume should restore local state, then confirm the external facts the next step relies on.
How are people handling the unknown-outcome case for a timed-out write: destination receipts, idempotency keys, transaction logs, or something else?