Restore an interrupted agent from durable task state, including completed actions and unresolved outcomes. A summary saying “send the report next” can be stale if the send completed just before the interruption.
The response can be lost after the action succeeds
An external service may accept an operation while the agent loses the acknowledgment. On restart, the absence of a success message is not proof that nothing happened. Preserve operation identities and use the downstream service’s documented reconciliation or idempotency mechanism where available.
Reconstruct the last durable boundary
- Load the task revision, authenticated actor, approved action details, and durable operation ledger.
- Reconcile actions marked in-progress or unknown before issuing another side effect.
- Resume planning from confirmed state rather than treating a generated summary as the authoritative ledger.
- Revalidate permissions and approval if circumstances or action details changed while the task was paused.
Interpret the local ledger
The example calls the same synthetic operation identity twice. Its in-memory ledger returns the recorded result on the second call without increasing the side-effect counter. This explains a retry invariant but is not a durable implementation: it will not survive process loss or coordinate concurrent workers.
Test the crash window in the real system
Exercise interruption before dispatch, after remote acceptance, before local persistence, and after completion. A durable local row alone cannot close every gap between two independent systems. Document the downstream contract and recovery path for uncertain operations; do not promise exactly-once execution without that evidence.
Run the worked example
Save the synthetic Node.js example and run node resume-interrupted-agent-without-duplicate-actions.mjs with Node.js 22 or newer. The assertions check the illustrated records and calculations; they do not test a deployed provider, SDK, or access control. No credentials or network connection are needed.
// Synthetic teaching fixture. No credentials, network calls, or production verification.
import assert from 'node:assert/strict';
const ledger = new Map();
let effects = 0;
const execute = operationId => {
if (ledger.has(operationId)) return ledger.get(operationId);
effects++;
const result = { receipt: 'synthetic-receipt-1' };
ledger.set(operationId, result);
return result;
};
assert.deepEqual(execute('operation-7'), execute('operation-7'));
assert.equal(effects, 1);
console.log('Same synthetic operation resumed without a second effect; persistence is not modeled.');
References and further reading
Maintained by DriftRail. AI assisted the October 2026 content and template revision. Examples are illustrative; they are not measured product benchmarks. Suggest a correction.