Vercel's durable-harness: crash-resume for Claude Code, Codex, Pi and OpenCode
An experimental open-source library that logs every model and tool call so cloud coding agents resume after a crash. For teams running harnesses 24/7.
Picture a two-person agency that runs Claude Code on a cloud VM so it can work through client tickets overnight. One job asks the agent to add a pricing page, open a pull request and wait for CI. Partway through the CI wait, the process dies: a timeout, an out-of-memory kill, a redeploy. In the morning someone notices and prompts the agent again. It re-reads files, re-calls the model and redoes work it had already finished. If the last step it was on was posting a PR comment, there may now be two. Nobody can say exactly which calls completed.
That is the failure Vercel describes in its announcement of durable-harness. A VM with persistent storage can host a harness, Vercel writes, but it "doesn't automatically record which model and tool calls completed or resume interrupted turns after a crash." durable-harness is a set of open-source adapters that write every step of a turn to a durable log, so a new process can pick the turn up where the old one died. It covers Pi, OpenCode, Codex and Claude Code, and runs on Vercel, on your own Postgres, or on your laptop. It is also explicitly experimental.
What it is
According to Vercel's post, durable-harness keeps a harness's session in a "World", the Workflow SDK's durable backend. Mapped to the pain above:
- Which calls finished? Before a model or tool call runs, the library records an intent. When the call finishes, it records the outcome. After a crash, the log says what finished, what was running and what never started.
- Who restarts the turn? Each turn is backstopped by a queue message. If its function dies, the queue hands the turn to a new function that reads the log and continues. If the browser disconnects, the agent keeps running and a reconnecting client catches up from the log.
- Paying twice. Completed calls are read from the log rather than rerun. Vercel says that means "you're never billed twice for a finished model call's tokens." That is the vendor's claim; no source measured it.
- Duplicate side effects. Each tool you define declares a replay policy. A
'safe'tool, like a file read or a CI status check, runs again after a crash. A'never'tool, like posting a PR comment or issuing a refund, is not rerun. Instead the model is told the call may have happened, so it can check first. - Harness-native state. Claude Code's transcript, Codex's rollout and OpenCode's event store are mirrored into the log, so a new function or Sandbox rebuilds them.
- Where files live.
virtual()keeps files in the session's log with a bash-compatible shell that can't reach the network.virtual({ durable: false })is scratch space cleared every turn.sandbox()gives the session its own Vercel Sandbox with/workspaceon a Drive that, per Vercel, outlives every sandbox and function. - Where it runs. On Vercel it uses the Vercel World, in development local files, and when self-hosted Postgres, MongoDB, Redis or Turso. On Vercel, the Agent Runs tab shows each session's trace, including turns that resumed after a crash.
The repo README describes each session as a workflow run whose conversation, in-flight turn and every model and tool call sit in the run's event log. Piagent's resource entry (updated Oct 19, 2026) repeats that description and lists the project at 151 GitHub stars, 8 forks and an Apache-2.0 license.
Alternatives the sources describe:
- A plain VM with persistent storage. Vercel's post concedes this replicates the local setup. Trade-off: you control everything, but nothing records completed calls or resumes a dead turn.
- AIOS. OSINTech's Oct 22 roundup lists it as "the local-first control plane for long-horizon coding agents," with cross-session project memory and resumable overnight runs on top of Codex CLI, Claude Code, Gemini CLI, OpenCode, Pi and others. Trade-off: local-first rather than cloud functions. No source compares its resume mechanism with durable-harness.
- Trigora. The same roundup describes it as "lightweight durable execution for long-running AI agents and programs." Trade-off: general-purpose, and no source covers harness integration.
The sources don't compare durable-harness with other durable-execution engines, so we won't.
Who it's for
Pick it up if you run a TypeScript and Next.js stack, keep Pi, OpenCode, Claude Code or Codex running unattended in the cloud, and have already lost turns to timeouts or crashes. It also fits builders of harness products. Vercel's post names OpenWork and HanaAgent as apps built on open-source harnesses. Teams already on Vercel get the most out of it, since managed storage, queuing and Agent Runs come with deployment, per the README.
Skip it if you need a stable API, if you want Claude Code or Codex entirely off Vercel infrastructure, or if your agents run interactively on a laptop. Vercel's own post notes that locally, resuming interrupted work "only requires a simple prompt." Non-Node stacks should wait too. A community proposal for a Python-based adapter is still asking maintainers whether they accept a non-Node-native runtime.
Before and after
Before (harness on a VM):
- Start the harness in a long-lived process with the session in memory.
- The agent reads the page, writes a new one, opens a PR and waits for CI.
- The process dies mid-turn.
- Someone notices and restarts it manually.
- The agent repeats completed work. Side-effecting steps may run twice, and finished model calls get paid for again.
After (same harness through durable-harness):
- Run the harness through its adapter, with your tools tagged
'safe'or'never'. - Each model and tool call logs an intent, then an outcome.
- The function dies. The queue hands the turn to a new function.
- The new function reads the log. Completed calls aren't rerun, safe tools run again, and never-tools go back to the model as "possibly run."
- If you're on Vercel, Agent Runs shows where the turn stopped and resumed.
Try it
The README's quickstart pairs Pi with pi-durable in a Next.js app:
npm install durable-harness @earendil-works/pi-durable @earendil-works/chord @earendil-works/pi-ai just-bash
You then open Pi's durable Harness in lib/agent.ts, serve it from a chat route, and wrap your Next.js config:
// next.config.ts
import type { NextConfig } from 'next';
import { withDurableHarness } from 'durable-harness/next';
const nextConfig: NextConfig = {
// your existing config
};
export default withDurableHarness(nextConfig);
Local development uses the Workflow SDK's local World with no configuration, per the README. To self-host on Postgres, Vercel's post says two variables move every agent:
WORKFLOW_TARGET_WORLD="@workflow/world-postgres"
WORKFLOW_POSTGRES_URL="postgres://user:password@host:5432/database"
The other harnesses have their own entry points: durable-harness/opencode, durable-harness/fx, durable-harness/claude-code and durable-harness/codex. Per Vercel, Claude Code's and Codex's built-in tools work on the session's Drive once you set builtins: true. Agents are tool-less by default, according to the README.
One setup tip from the issue tracker: list your agent modules explicitly instead of relying on default discovery (see below). None of the sources cover pricing for running on Vercel.
Where it breaks
- It's 0.0.x. The README says the library is experimental and its API may change between releases. Bug reports filed Oct 21, 2026 cite 0.0.1-beta.6.
- A 30-second stall on the local World. An independent crash test killed durable-harness sessions on
@workflow/world-local5.1.2 mid-turn. When the kill left a lock directory behind, 7 runs took 30.4–33.6 s to finish resuming. Without a leftover lock, 6 runs took 0.6–4.4 s. In an earlier sweep, 13 of 20 kills before the first tool call stalled. The reporter proposes a fix based on the lock holder's process ID. This affects the local World specifically. The sources don't say whether other Worlds behave the same way. - Build-time surprises. Issue #20 reports that
withDurableHarness, without an explicit agents list, uses a text match to find agent modules. That pulled a crash-drill script and a docs page containing a code sample into the generated flow route.next build(Next.js 16.4.2) ran the script's top-level code twice, and the build still exited 0. The workaround is listing agents, for examplelib/agent.ts. - Side effects remain your problem. For
'never'tools, the model is told the call may have happened. Whether resume ever retries such calls, and whether idempotency keys are expected, is not confirmed by any source. Our analysis: keep your own APIs idempotent anyway. - Sandbox state is partly unconfirmed.
/workspacelives on a Drive that outlives sandboxes. Whether running processes or files outside the workspace survive a crash is not covered. - Lock-in. The README says Claude Code and Codex run only in the session's own Vercel Sandbox, never in a shared Function. No source confirms whether self-hosting on Postgres removes that dependency for those two harnesses. Agent Runs is a Vercel feature.
- Cost is unknown. No source covers billing for always-on runs on Vercel's functions, queues and sandboxes.
Who picks this: a Node shop already running Pi, OpenCode, Claude Code or Codex unattended, ideally on Vercel, that will tolerate beta churn in exchange for turn-level resume. Who skips it: anyone needing a stable API, a non-Vercel home for Claude Code or Codex, or a cost estimate before committing.
Sources
- Making every harness durable · Vercel
- GitHub - vercel-labs/durable-harness: Durable coding-agent harnesses (Claude Code, Codex, OpenCode, Pi, fx) on a Workflow SDK World · GitHub
- withDurableHarness: default agent discovery imports scripts and pages into the flow route, and next build runs them · Issue #20 · vercel-labs/durable-harness · GitHub
- Proposal: add agx / agx-coding durable harness adapter (thin coding slice) · Issue #21 · vercel-labs/durable-harness · GitHub
- world-local: a process killed while holding a run's in-band fence lock stalls that run for 30 s · Issue #4967 · vercel/workflow · GitHub
- durable-harness — Resource Map | Piagent · Piagent
- OSINTech's Timeline (185) - 22.10.2026 · OSINTech’s OSINT Anatomy Substack