Find and recover stuck runs
Inspect stored state, export observations, and choose the right recovery action.
When work looks stuck, start with the stored run and its events. Logs and traces can explain an execution, but durable state tells you what Runlane believes now.
Run lists and event searches require a lane with OperatorReadDriver. This is separate from transactional storage. A lane can execute tasks correctly without offering indexed operator queries. The first-party Local and PostgreSQL providers support both.
Inspect the stored run
Put programmatic inspection in an operator-only server module, for example src/runlane/inspect-run.ts:
import { type RunId, type RunlaneRuntime } from '@runlane/core'
export async function inspectRun(runlane: RunlaneRuntime, runId: RunId) {
const run = await runlane.runs.get(runId)
const attempts = await runlane.runs.attempts(runId)
const events = await runlane.runs.events(runId)
return { attempts, events, run }
}Check the current status, due time, lease, failure code, attempt summaries, and event order. You can inspect the same data from the CLI:
npm exec -- runlane runs get <run-id> --eventsBuild alerts around stable Runlane error codes. Keep raw provider causes in server logs; do not send them directly to clients.
Export durable observations
Live observers receive sanitized facts after persistence. Runtime telemetry emits operational logs, metrics, and spans. Both are best-effort; see export traces, metrics, and logs for OpenTelemetry setup.
For checkpointed delivery of persisted run events, completed steps, and wait-token transitions, enable durable observation storage on every runtime and export durable observations. Stop the exporter before closing its storage connection, and monitor export failures separately from task execution.
Choose the matching recovery action
- Fix worker, queue, maintenance, or transport health when valid work is not moving.
- Use
runs.cancel()when the work is no longer wanted. - Use
runs.retry()after fixing the cause of a failed run. - Use
runs.rerun()when you want a new execution of terminal work.
Both operations create a new run from the source run's saved validated payload without applying the input schema again. The new run has its own step checkpoints. Keep the registered handler compatible with the saved payload shape.
Do not hide a stuck run with an unrelated trigger. That loses the source link and can bypass operator policy.
In a non-production environment, test delivery failure, lease expiry, and export failure separately. Confirm that durable state remains readable, maintenance recovers eligible work, and the export checkpoint moves only after the sink succeeds.