Cloudflare Pi task stuck on “parked”? How to resume it
Your app still shows progress, but its Pi task stopped restarting and wait() never returns. What brings it back, and is rolling back to Pi 1.3 an option?

- Agents SDK 0.30.0 runs PiHarness on Pi 1.4 and exposes crash-looped work as parked.
- wait() does not finish just because the task is parked; inspect and explicitly resume or abort it.
- Pi 1.3 cannot open migrated SQLite session storage, so reverting code is not a complete rollback.
A parked task is unresolved work
A PiHarness operation marked parked will not recover merely because a caller waits longer. Agents SDK 0.30.0, announced October 22, supports Pi 1.4’s guard against repeatedly restarting work that makes no progress.
The default restart limit is five. It counts consecutive interruptions by crashes, evictions or resets before a task commits a new state. Committing new state resets the count. This is not a count of incorrect model answers or every API error.
Every running task interrupted by the process dying is counted. A parked task is therefore not necessarily the individual cause of the crash. Investigate the resource limit or execution path that interrupted it.
Inspect the status before deciding to retry
Cloudflare documents that parked work remains visible in pending(), while wait() keeps waiting. Applications should expose that state instead of presenting an unexplained spinner.
| Method | Purpose |
|---|---|
session.pending() | Inspect unsettled operations: queued, running or parked. |
session.retry() | Restart tasks stopped by the restart limit; returns false if none were parked. |
session.abort() | With no operation ID, abort the session’s work. |
Fix the cause before retrying. Repeatedly pressing retry does not repair a task that exhausts the same resources. For a queued operation, abort(operationId) withdraws that operation. If it has joined a run, the call aborts that run.
The session API also distinguishes cancellation of a wait from cancellation of work: aborting the signal passed to wait(operationId, signal) only stops waiting.
Recovery does not blindly repeat every tool call
After an ordinary crash, a wake-up alarm resumes work from the last checkpoint. An interrupted tool declared replay: "safe" runs again. Other tools deliver an interrupted result to the model, which decides what to do next.
Safe replay means that running the operation twice is harmless. A card charge needs different treatment from a read. Pi’s tool documentation also requires replayable tools with external effects to provide their own idempotency. Durable execution alone does not establish that an external action happened exactly once.
Plan for the storage change as well as the new status
Pi 1.4 automatically migrates SQLite storage to schema version 2. Pi 1.3.0 and earlier cannot open it. Reinstalling the previous deployment cannot undo that data-format change.
The SDK upgrade instructions include matching Pi packages to ~1.4.0 and adding @earendil-works/chord. Pass the factory’s onWake into Harness.open() so sleeping work can let the object hibernate.
Move a module-scoped registry into the instance, keep the factory safe to run again after storage errors, and handle parked in status branches. A crash-loop guard becomes useful operationally when the application can show stopped work and provide a deliberate recovery path.