paperclipai/paperclip · error · RunnerWorkflowInfrastructureError
live_provider_execution_failed
live_provider_execution_failed
Error message
live_provider_execution_failed
What it means
executeLiveRunnerWorkflow wraps a live (real provider) eval session; any error raised while creating, messaging, restoring, or shutting down the live session is captured, the runtime root is deleted, and rethrown as RunnerWorkflowInfrastructureError with code live_provider_execution_failed and retryable=true. This code marks the failure as infrastructure (provider/transport/process) rather than an assertion failure, so the failure message is the stringified underlying cause.
Source
Thrown at packages/paperclip-runner/src/eval/live-workflow-executor.ts:941
unsubscribe();
if (budgetInterrupt !== null) await budgetInterrupt;
if (budgetInterruptError !== undefined) throw budgetInterruptError;
}
} catch (error) {
infrastructureError = error;
}
const snapshot = session?.snapshot();
if (session !== null) {
try {
await service.shutdown(session.id, "Runner live workflow eval complete");
} catch (error) {
infrastructureError ??= error;
}
}
if (infrastructureError !== undefined) {
await rm(runtimeRoot, { recursive: true, force: true });
throw new RunnerWorkflowInfrastructureError(
"live_provider_execution_failed",
true,
safeFailureMessage(infrastructureError),
);
}
const calls = snapshot === undefined ? [] : observedCalls(snapshot);
const expectedCalls = input.evalCase.assertions.requiredOperationIds ?? [];
const taskState =
snapshot === undefined
? null
: ((
JSON.parse(snapshot.mockState) as {
tasks?: Array<{ id: string; status: string }>;
}
).tasks?.find((task) => task.id === "task-1") ?? null);
const terminalStatuses = turns.map((turn) => turn.status);
const cancellationExpected = input.evalCase.id === "cancellation-permissions";
const terminalOkay = cancellationExpectedView on GitHub (pinned to 01ad858492)
Solutions
- Read the wrapped cause via safeFailureMessage in the error's message/detail to identify the underlying provider or transport failure.
- Check provider credentials and environment variables required by the candidate's qualification.requiredEnvironment/profile before running the campaign.
- Confirm network egress to the provider endpoint and that the requested model is enabled for the account.
- Re-run: the error is flagged retryable=true, so transient provider outages and rate limits can be retried within maxAttempts.
- If it reproduces, raise budget.maxLatencyMs/maxCostUsd for the candidate or run a single eval case to isolate whether startup, messaging, or shutdown fails.
Defensive patterns
Strategy: retry
Validate before calling
// Before the live run, check provider reachability and env:
for (const envName of candidate.qualification.requiredEnvironment) {
if (!process.env[envName]) throw new Error(`missing ${envName} for live provider ${candidate.provider}`);
}
// Optionally probe the provider endpoint health before starting the campaign. Type guard
function isInfrastructureError(e: unknown): e is RunnerWorkflowInfrastructureError {
return e instanceof RunnerWorkflowInfrastructureError && e.code === "live_provider_execution_failed";
} Try / catch
try {
await executeLiveRunnerWorkflow(input);
} catch (error) {
if (error instanceof RunnerWorkflowInfrastructureError && error.code === "live_provider_execution_failed" && error.retryable) {
// back off and retry within candidate.budget.maxAttempts;
// inspect error message for the wrapped provider/transport cause
} else {
throw error;
}
} Prevention
- Validate all qualification.requiredEnvironment credentials before launching a live campaign.
- Set realistic budget.maxLatencyMs and maxCostUsd per candidate so provider latency does not read as infrastructure failure.
- Prefer warm lifecyclePolicy with an adequate idleTimeoutMs for multi-turn cases like restart-recovery.
- Check provider status pages / rate limits before scheduled rotation runs; the error is retryable by design.
- Run a single eval case first to isolate whether startup, messaging, or shutdown is the failing phase.
When it happens
Trigger: Any throw inside the session lifecycle during the live run: CapabilityLiveSessionService failing to start the adapter process, sendMessage rejecting on provider API error/timeout (turnTimeoutMs exceeded), session.restore failing during the restart-recovery case, budget-interrupt errors thrown in the finally block, or service.shutdown rejecting after the run.
Common situations: Expired or missing provider API credentials; provider rate limits or 5xx; model name not available to the account; network egress blocked in CI; turn latency exceeding maxLatencyMs budget; adapter binary failing to launch (e.g. the trusted opencode binding errors); shutdown racing an already-dead session.
Related errors
- provider turn ended with status ${turn.status}
- PAPERCLIP_EVAL_MAX_CAMPAIGN_COST_USD must be a positive fini
- Runner live rotation requires a valid generated-at time
- schedule references unknown candidate ${entry.candidateId}
- live schedule coverage failed: ${JSON.stringify(coverage)}
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-02).
Data as JSON: /api/errors/023fa7a867eb62f4.
Report an issue: GitHub.