Skip to main content

Start here

1

Read the run

Call get_run and look at status, failure_reason, and errors. Agent runs also have failure_category.
2

Watch it

Open app_url in the app, or download the recording. Most failures are obvious once you see the page the agent saw.
3

Find the cause below

Match the failure category or the symptom, then apply the fix.
What each status means, and whether to retry, is on Going to production.

Failure categories

When an agent run ends in failed, terminated, or timed_out, Skyvern classifies the cause. The app shows the label as a badge on the run. The API and webhooks return the code in failure_category[0].category. A category that isn’t in this table is one of your own error_code_mapping codes, shown as is.

Common problems

Run results

Cause: the agent ended on the wrong page, picked a similar element, or the goal was ambiguous.Fix: check screenshot_final to confirm the page. Add descriptions to your schema fields, such as "description": "Price in USD, without the currency symbol". Add a visual hint: “The price is in bold under the product title.”
Fix: add “Only extract values visibly shown on the page. Return null if a value is missing.” Make schema fields that can be absent optional.
Cause: the run used its max_steps budget. Status is failed and errors contains REACH_MAX_STEPS. Common reasons: the goal has no clear finish line, the agent is looping, or the task really needs more steps.Fix: add a completion rule (“COMPLETE when you see ‘Order confirmed’”). Watch the recording for a repeating pattern. Raise max_steps (tasks) or max_steps_override (agent runs), or split the work into several blocks.
Cause: an agent run passed max_elapsed_time_minutes (default 240).Fix: narrow the goal, split the agent, or raise the limit (maximum 480).
Fix: state the finish line, including the final click: “COMPLETE when you have clicked Submit AND see a confirmation.” Add a stop rule: “TERMINATE if you have tried this three times.” If a Task block clicks through every page when you wanted one click, use an Action or Navigation block.
Cause: your organization is at its concurrency limit, or the agent has Prevent Overlapping Runs on and an earlier run with the same Sequential Key (optional) is still running.Fix: wait for earlier runs to finish, or cancel stuck ones.
Cause: the request can never start: a required input has no value, a credential ID doesn’t exist in your organization, or a value has the wrong type. The detail message names the input.Fix: correct the request. Retrying unchanged returns the same 400.

Page and element problems

Cause: the element loads late, sits in an iframe or below the fold, or several elements look alike.Fix: describe it by what’s visible: “the blue Download button in the row for January 2026.” Set max_screenshot_scrolls so the agent scrolls before reading. Check visible_elements_tree to see whether Skyvern detected the element at all. If a visible, standard element is never detected, report it.
Fix: “Type ‘Toronto’, select the first matching suggestion, then move to the next field without changing it.”
Fix: give the exact format: “Enter 15/01/2026 (DD/MM/YYYY).” For pickers: “Open the date picker and select January 15, 2026.”
Fix: name the exact control: “Click the PDF button, not the Excel one.” Check downloaded_files on the run.
The agent presses single keys such as Enter, Tab, and Escape. It can’t use browser or OS shortcuts. Prefer a visible button (“click the X to close the dialog”). If the site has no alternative, use a Code block: await page.keyboard.press("Escape").
Cause: the site localizes by IP.Fix: pick a matching proxy_location, or open a language-specific URL such as https://example.com/en/.

Login and 2FA

Cause: the credential isn’t linked to the agent’s Login block, the credential ID is wrong, or the password manager connection failed.Fix: confirm the credential exists with GET /v1/credentials/{credential_id}, and that the Login block uses it. For Bitwarden or 1Password, check the vault connection. See Credentials and 2FA.
Fix: log in by hand with the same values. Check whether the site wants an email or a username, and remove trailing spaces from the stored values.
Skyvern already waits for a fresh TOTP code when fewer than 20 seconds are left and the code goes into several boxes. A pushed code stays usable for 10 minutes, but the site’s own code may expire sooner, so forward codes as soon as they arrive. Self-hosted servers need an accurate clock (NTP). errors shows OTP_EXPIRED in this case.
Cause: the push never reached Skyvern, totp_identifier differs between the run and the push, or your totp_url endpoint returns errors. errors shows OTP_TIMEOUT or OTP_ERROR.Fix: list received codes with GET /v1/credentials/totp?totp_identifier=.... Make sure the identifier matches exactly. See Credentials and 2FA.
Fix: use a direct username and password if the site offers one. Otherwise sign in once in a browser session or profile and reuse it.

Bot checks, proxies, and sessions

See Anti-bot and CAPTCHA. In short: residential or ISP proxy, a saved browser profile, more steps, slower actions, or Take control to solve it yourself.
Fix: widen the GeoTarget from city to state to country, or retry later.
Fix: retry after a few seconds. On self-hosted servers, check CPU and memory. If it persists, contact support with the session or run IDs.
Fix: call get_run, since the result is stored either way. Then fix the endpoint and call retry_run_webhook. See Retries and replay.

Self-hosted

Fix: send the key in the x-api-key header, exactly as generated, with no trailing newline. With Docker Compose, the key is the cred value in .skyvern/credentials.toml.
Fix: run docker compose logs skyvern. The usual causes are a missing LLM key or a database that isn’t healthy yet (docker compose ps).
Fix: check VITE_API_BASE_URL and VITE_WSS_BASE_URL in skyvern-frontend/.env, then docker compose restart skyvern-ui.
Fix: set LLM_KEY to your provider’s key (for example OLLAMA) and enable that provider, then restart. See Self-host.
Cause: inside a container, localhost is the container.Fix: use http://host.docker.internal:<port>.

Use artifacts

Every run records what happened: a video, screenshots, the AI’s prompts and answers, the page structure it saw, logs, and network traffic. Fetch them with get_run_artifacts, optionally filtered by type.
signed_url links for screenshots and recordings expire after 1 hour; other links follow your organization’s Artifact URL Expiry (12 hours by default). Call again for fresh ones. On a self-hosted server with local storage, signed_url is the file’s location on the server’s disk. To see which block failed in an agent run, call get_run_timeline.

Get help

Send support the run_id, what you expected, and what happened. Use the chat in the app, email support@skyvern.com, or ask on Discord.

Next