different-ai/openwork · error · Error
Desktop Automation execution timed out
Error message
Desktop Automation execution timed out
What it means
The polling loop in executeDesktopAutomation enforces assignment.timeoutMs via a wall-clock deadline checked at the top of every iteration. If the assistant thread has not produced a terminal result before the deadline, execution is abandoned with this timeout error (the thread is aborted via the registered abort listener).
Source
Thrown at apps/desktop/electron/automation-runner.mjs:179
const workspace = resolveAssignmentWorkspace(listed, assignment.workspaceId ?? null)
const workspaceId = String(workspace.id)
const client = createWorkspaceSessionClient(local, workspaceId, options.fetchImpl ?? fetch)
const created = await client.createThread({
title: `Automation: ${assignment.automationName}`.slice(0, 120),
...(assignment.instructions ? { prompt: assignment.instructions } : {}),
model: assignment.model,
signal: options.signal,
})
const sessionId = created.id
// The assignment signal is already aborted when this listener runs. Do not
// pass it to the cleanup request or fetch can reject before reaching OpenCode.
const abort = () => void client.abortThread(sessionId).catch(() => undefined)
options.signal.addEventListener("abort", abort, { once: true })
try {
const startedAt = Date.now()
const deadlineAt = startedAt + assignment.timeoutMs
while (true) {
if (Date.now() > deadlineAt) throw new Error("Desktop Automation execution timed out")
// The wall-clock check above only runs between awaits. A machine that
// suspends mid-request can leave this socket half-open with no error,
// which would make the assignment timeout unreachable: bound each poll
// by the remaining execution budget so the deadline always fires.
let snapshot
try {
snapshot = await client.getThreadSnapshot(sessionId, {
signal: AbortSignal.any([options.signal, AbortSignal.timeout(Math.max(1, deadlineAt - Date.now()))]),
limit: 200,
})
} catch (error) {
if (!options.signal.aborted && Date.now() >= deadlineAt) throw new Error("Desktop Automation execution timed out")
throw error
}
const output = assistantResult(snapshot)
const snapshotError = assistantFailure(snapshot)
if (snapshotError) {
const error = new Error(snapshotError.message)View on GitHub (pinned to 2b7df46e8a)
Solutions
- Increase assignment.timeoutMs to cover the expected task duration
- Investigate why the thread never went idle/produced a result (check session logs)
- Break the task into smaller assignments with shorter scopes
- Check for permission prompts blocking the automated thread
Example fix
// before: default 60s timeout for a long research task
const assignment = { prompt: "deep research...", timeoutMs: 60_000 };
// after
const assignment = { prompt: "deep research...", timeoutMs: 15 * 60_000 }; Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure the budget covers the task before submitting
const estimatedMs = estimateTaskDuration(assignment.prompt);
if (estimatedMs >= assignment.timeoutMs) {
assignment.timeoutMs = Math.max(assignment.timeoutMs, estimatedMs * 2);
} Try / catch
try {
const result = await executeDesktopAutomation(assignment, options);
} catch (err) {
if (err.message === "Desktop Automation execution timed out") {
// thread already aborted; retry with a larger budget
await executeDesktopAutomation({ ...assignment, timeoutMs: assignment.timeoutMs * 2 }, options);
} else throw err;
} Prevention
- Set timeoutMs generously for long-running agent tasks
- Monitor thread progress between polls and log last activity time
- Avoid scheduling automations that require interactive permissions
- Alert on timeout-rate trends per task type
When it happens
Trigger: getThreadSnapshot polling looped past startedAt + assignment.timeoutMs without the thread reaching a result — e.g. the agent task legitimately runs longer than the configured timeout, or polling stalls.
Common situations: Assignment timeoutMs configured too low for a long-running agent task; agent stuck waiting on user input/permission prompt; slow model responses; machine under heavy load slowing execution.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Agent context diagnostics timeout must be between 1 ms and 3
- Request timed out.
- Timed out waiting for server health
- Authorization for ${input.connectionName} did not finish. Co
- Connection lost
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/e7e4a0c826c6b72f.
Report an issue: GitHub.