> ## Documentation Index
> Fetch the complete documentation index at: https://checkly-422f444a-simo-red-1015-maintenance-window-timezone.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Debug a failed check

> Go from a failing Playwright check to its root cause with the Checkly CLI, the Playwright trace in your terminal, and Rocky AI, then confirm the fix with a test run before you deploy.

export const CopyPromptButton = ({label = "Copy setup prompt", targetId = "ai-setup-prompt"}) => {
  const [copied, setCopied] = useState(false);
  const handleCopy = async () => {
    try {
      const el = document.getElementById(targetId);
      const code = el?.querySelector("code");
      const text = code?.textContent || el?.textContent || "";
      await navigator.clipboard.writeText(text);
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    } catch (err) {
      console.error("Failed to copy prompt:", err);
    }
  };
  return <button onClick={handleCopy} className="inline-flex items-center gap-2 px-5 py-3 rounded-lg font-semibold text-base
        border border-gray-200 dark:border-gray-700
        bg-white dark:bg-gray-800
        text-gray-800 dark:text-gray-200
        hover:bg-gray-50 dark:hover:bg-gray-700
        transition-colors cursor-pointer my-2">
      {copied ? <>
          <svg width="18" height="18" viewBox="0 0 16 16" fill="none">
            <path d="M13.3 4.3L6 11.6L2.7 8.3" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
          </svg>
          Copied!
        </> : <>
          <svg width="18" height="18" viewBox="0 0 16 16" fill="none">
            <rect x="5" y="5" width="9" height="9" rx="1.5" stroke="currentColor" strokeWidth="1.5" />
            <path d="M11 5V3.5C11 2.67 10.33 2 9.5 2H3.5C2.67 2 2 2.67 2 3.5V9.5C2 10.33 2.67 11 3.5 11H5" stroke="currentColor" strokeWidth="1.5" />
          </svg>
          {label}
        </>}
    </button>;
};

By the end of this guide, you have taken a failing check from the alert to its root cause without leaving the terminal, confirmed the diagnosis with a recorded test run, and deployed the fix.

<Frame>
  <img src="https://mintcdn.com/checkly-422f444a-simo-red-1015-maintenance-window-timezone/VdlVih9ongP3hoLV/images/guides/debug-failed-check/check-detail.png?fit=max&auto=format&n=VdlVih9ongP3hoLV&q=85&s=f35de4c327fc2633fd30753c24311f23" alt="The Shop checkout check detail page in Checkly, with failed runs from N. Virginia and Ireland followed by a passing run after the fix" width="2400" height="1800" data-path="images/guides/debug-failed-check/check-detail.png" />
</Frame>

To follow along, clone the [sample project](https://github.com/checkly/docs/tree/main/samples/guides/debug-failed-check). It monitors the checkout of the [Danube demo shop](https://danube-web.shop), and it fails on purpose.

<Accordion title="Let your agent do it" icon="sparkles">
  To run this guide from your terminal or your coding agent, run `npx checkly init` in your project first. It installs the Checkly CLI and [Checkly Skills](/ai/skills) for your agent. Then paste the prompt below into Claude Code, Cursor, Codex, or any agent that supports skills. It builds the same setup as this guide, proves it with `npx checkly test --record`, and stops for your confirmation before `npx checkly deploy`.

  <div id="ai-setup-prompt">
    ```txt Prompt theme={null}
    The Checkly check "Shop checkout" in this project is failing. Find the root cause and prove it.

    Success criteria:
    1. Run `npx checkly checks list --status=failing` and `npx checkly checks get <id>` to find the failing result and its error group.
    2. Read the root cause analysis with `npx checkly checks get <id> --error-group <error-group-id>`. Treat it as a hypothesis, not a verdict.
    3. Download the Playwright trace with `npx checkly assets download` and read it with `npx playwright trace`: list the actions, show the failing action, list the requests, and extract the error-context attachment.
    4. Tell me the root cause in two sentences, with the evidence from the trace that supports it.
    5. Propose the smallest change to `tests/checkout.spec.ts` that confirms the diagnosis, apply it, and run `npx checkly test --record`. Show me the session link.
    6. Wait for my confirmation before `npx checkly deploy`.
    ```
  </div>

  <CopyPromptButton />

  The steps below are what the agent does, in the open.
</Accordion>

## Step 1: Find what failed

An alert tells you a check failed. Start from the terminal, not the dashboard. List the failing checks and open the one from the alert.

```bash Terminal theme={null}
npx checkly checks list --status=failing
```

```text Terminal theme={null}
✔ 80 passing    ⚠ 1 degraded    ✖ 2 failing    (2 total checks)

NAME                 TYPE        STATUS    FREQ  TAGS                   ID
Shop checkout        PLAYWRIGHT  failing   10m   shop, checkout         8c688bf9-2c0a-4614-be7b-e66008b1093a
```

```bash Terminal theme={null}
npx checkly checks get 8c688bf9-2c0a-4614-be7b-e66008b1093a
```

```text Terminal theme={null}
Shop checkout

Type:       PLAYWRIGHT
Status:     failing
Frequency:  Every 10m
Locations:  us-east-1, eu-west-1

ERROR GROUPS
ERROR                                                       FIRST SEEN    LAST SEEN     RCA   ERROR GROUP ID
Error: expect(locator).toBeVisible() failed Locator: getB…  2m ago        4s ago        Yes   0653dbc0-9c7c-4eae-9417-deed85074a2e

RECENT RESULTS
TIME          LOCATION   STATUS    RESPONSE TIME   RESULT ID
41s ago       eu-west-1  failing   35.74s          01a0df0e-99a6-7379-aab4-9e3f0bfcf420
43s ago       us-east-1  failing   29.00s          01a0df0e-8e55-725d-978d-5b4b89c5a664
```

Two things matter here. Every result fails with the same error, so Checkly has folded them into one error group. And it fails from both locations, so this is not a regional blip. The `RCA` column says Rocky AI has already analyzed the group.

## Step 2: Read the error and the analysis

Open the error group. It prints the full Playwright error with the failing line, and below it the root cause analysis.

```bash Terminal theme={null}
npx checkly checks get 8c688bf9-2c0a-4614-be7b-e66008b1093a --error-group 0653dbc0-9c7c-4eae-9417-deed85074a2e
```

```text Terminal theme={null}
FULL ERROR
Error: expect(locator).toBeVisible() failed

Locator: getByText('All good, order is on the way. Thank you!!')
Expected: visible
Timeout: 5000ms
Error: element(s) not found

  19 |   await page.getByRole('button', { name: 'Buy' }).click()
  20 |
> 21 |   await expect(page.getByText('All good, order is on the way. Thank you!!')).toBeVisible()
     |                                                                              ^

ROOT CAUSE ANALYSIS

Classification: PLAYWRIGHT_CODE_ERROR
Root cause:     The test immediately asserts that the success message "All good, order is on the way. Thank you!!" is visible without filling any checkout fields, so the page correctly shows a validation error instead of the success state. ...

  EVIDENCE
  · PLAYWRIGHT_TRACE — All three traces show the DOM snapshot at failure with the checkout form still present, validation message `Please fill in all fields.` and the `Buy` button, but no element containing the expected success text, ...
```

The error says what did not happen: the order confirmation never appeared after **Buy**. Rocky read the trace and found what happened instead: the form showed `Please fill in all fields.`. That is the lead.

Rocky's conclusion is a hypothesis, and this one is wrong in a detail that matters. Open the spec: it fills name, surname, address, zipcode, and city. Checkly scrubs form input values from stored traces, so the analysis could not see them. Whenever the analysis and your code disagree, the trace decides.

<Note>
  Rocky analyzes every new error group automatically. To rerun it with what you know, use `npx checkly rca run --error-group <id> --user-context "..." --watch`.
</Note>

## Step 3: Look at the result

The result page has the failure screenshot, the video, and the trace viewer. It is the quickest way to see what the browser saw, and it is what the alert links to.

<Frame>
  <img src="https://mintcdn.com/checkly-422f444a-simo-red-1015-maintenance-window-timezone/VdlVih9ongP3hoLV/images/guides/debug-failed-check/result-failed.png?fit=max&auto=format&n=VdlVih9ongP3hoLV&q=85&s=71191ff19f6788471ed69f3c60271fdf" alt="The failed Shop checkout result in Checkly with the Run, Retry 1, and Retry 2 tabs, the View Trace, Screenshots, Video, and Analyze root cause buttons, and the Playwright error with line 21 highlighted" width="2400" height="1660" data-path="images/guides/debug-failed-check/result-failed.png" />
</Frame>

Open the screenshot. The checkout form is still on screen, five fields are filled, the company field is empty, and the form says `Please fill in all fields.`.

<Frame>
  <img src="https://mintcdn.com/checkly-422f444a-simo-red-1015-maintenance-window-timezone/VdlVih9ongP3hoLV/images/guides/debug-failed-check/failure-screenshot.png?fit=max&auto=format&n=VdlVih9ongP3hoLV&q=85&s=a428604bcff197d18c42fc00c7fa4ea3" alt="The Danube shop checkout form at the moment of failure: name, surname, address, zipcode, and city filled in, the Company (optional) field empty, and the message Please fill in all fields above the Buy button" width="1280" height="720" data-path="images/guides/debug-failed-check/failure-screenshot.png" />
</Frame>

That is a strong lead, and a screenshot is one frame. The trace tells you what the click did and what the page looked like as text you can search.

## Step 4: Read the trace in the terminal

Download the trace for the failed result. Every asset belongs to one result, so pass the result ID and the check ID from step 1.

```bash Terminal theme={null}
npx checkly assets download --check-id=8c688bf9-2c0a-4614-be7b-e66008b1093a --result-id=01a0df0e-99a6-7379-aab4-9e3f0bfcf420 --type=trace
```

```text Terminal theme={null}
Downloaded archive asset
Path: ./checkly-assets/check-result-01a0df0e-99a6-7379-aab4-9e3f0bfcf420/assets.zip
```

Unzip it and open the first attempt's trace with Playwright's terminal trace viewer. It needs Playwright 1.59 or later.

```bash Terminal theme={null}
unzip -q checkly-assets/check-result-01a0df0e-99a6-7379-aab4-9e3f0bfcf420/assets.zip -d checkly-assets/result
npx playwright trace open checkly-assets/result/test-results/checkout-checkout-completes/trace.zip
npx playwright trace actions
```

```text Terminal theme={null}
   19. 0:02.353  Fill "Berlin"                                                37ms
                 getByPlaceholder('City')
   20. 0:02.392  Check                                                       83ms
                 getByLabel('as soon as possible')
   21. 0:02.476  Click                                                       82ms
                 getByRole('button', { name: 'Buy' })
   22. 0:02.561  Expect "toBeVisible"                                        5.0s  ✗
                 getByText('All good, order is on the way. Thank you!!')
```

Every field was filled and **Buy** was clicked. Then the expectation waited five seconds for a confirmation that never came. Check what the click did on the network.

```bash Terminal theme={null}
npx playwright trace requests
```

```text Terminal theme={null}
   18. GET      304      logo-horizontal.svg                                 73ms        -
   19. GET      200      books                                               72ms       19
   20. POST     200      logs                                               176ms       88
```

No order was sent. The last request to the shop is the cart's `books` lookup, before the click. Whatever stopped the order happened in the browser, so look at the page as it was when the test failed. Playwright attaches it as `error-context`.

```bash Terminal theme={null}
npx playwright trace attachments
npx playwright trace attachment 4
```

```text Terminal theme={null}
    - textbox "Name" [ref=e21]: Max
    - textbox "Surname" [ref=e22]: Mustermann
    - textbox "Address" [ref=e23]: Musterstrasse 1
    - textbox "Zipcode" [ref=e24]: "10115"
    - textbox "City" [ref=e25]: Berlin
    - textbox "Company (optional)" [ref=e26]
    - text: I would like the items to be shipped
    - radio "as soon as possible" [checked] [ref=e27]
    ...
    - paragraph: Please fill in all fields.
    - button "Buy"
```

There is the root cause. Five fields are filled, the sixth is labelled optional and empty, and the form refuses to submit with `Please fill in all fields.`. The check is doing exactly what a customer without a company would do, and that customer cannot buy. This is an application bug, not a monitoring bug.

<Tip>
  Point your coding agent at the same trace with `npx playwright trace install-skill`. [Debugging with AI agents](/learn/playwright/debugging-with-ai-agents) covers the full text-first toolchain.
</Tip>

## Step 5: Confirm the diagnosis, then ship

A root cause is a claim until a change proves it. If the company field is the cause, filling it should make the check pass. Fill it, and leave a comment that says why, so nobody mistakes the workaround for the intended flow.

```ts tests/checkout.spec.ts highlight={18-20} theme={null}
import { test, expect } from '@playwright/test'

test('checkout completes', async ({ page }) => {
  await page.goto('/')

  await page.locator('.preview:nth-child(1) > .preview-author').click()
  await page.getByRole('button', { name: 'Add to cart' }).click()
  await page.locator('#logo').click()

  await page.locator('#cart').click()
  await page.getByRole('button', { name: 'Checkout' }).click()

  await page.getByPlaceholder('Name', { exact: true }).fill('Max')
  await page.getByPlaceholder('Surname', { exact: true }).fill('Mustermann')
  await page.getByPlaceholder('Address').fill('Musterstrasse 1')
  await page.getByPlaceholder('Zipcode').fill('10115')
  await page.getByPlaceholder('City').fill('Berlin')
  // The form rejects an empty company field even though the label says optional.
  // Fill it so the rest of the flow stays monitored while the app fix ships.
  await page.getByPlaceholder('Company (optional)').fill('Checkly')
  await page.getByLabel('as soon as possible').check()
  await page.getByRole('button', { name: 'Buy' }).click()

  await expect(page.getByText('All good, order is on the way. Thank you!!')).toBeVisible()
})
```

Run it on Checkly without deploying. The deployed monitor keeps running the old code until you say otherwise.

```bash Terminal theme={null}
npx checkly test --record
```

```text Terminal theme={null}
Running 1 checks in eu-west-1.

playwright.config.ts
  ✔ Shop checkout (11s)

1 passed, 1 total

Detailed session summary at: https://chkly.link/l/zbPNj
```

It passes, so the diagnosis holds. File the bug against the checkout form with the trace attached. Then deploy, so the monitor covers the rest of the checkout while the fix ships.

```bash Terminal theme={null}
npx checkly deploy
```

## Verify it works

Run the deployed check instead of waiting for its next scheduled run.

```bash Terminal theme={null}
npx checkly checks run --tags=checkout
```

```text Terminal theme={null}
1 check session completed: 1 passed.

STATUS     NAME              TYPE        LOCATIONS     DURATION  CHECK ID                              SESSION ID
passed     Shop checkout     PLAYWRIGHT  eu-west-1     9s        8c688bf9-2c0a-4614-be7b-e66008b1093a  01a0df11-61cc-7330-b673-0e752811097e
```

The check is passing again, and the failed runs and the recovery are on the check page.

The same investigation works from a chat client with the [Checkly MCP Server](/ai/mcp-server) connected, which is where you are when the alert lands on your phone. The server's tools read live results, error groups, and analyses, and download the same assets.

```text Prompt theme={null}
Investigate the failing "Shop checkout" check. Read its error group and any existing root cause analysis, then tell me whether this is an application problem or a test problem and what evidence supports that.
```

The agent calls `list-check-stats` with the failing filter to find the check, `get-error-group-root-cause-analyses` to read the group and Rocky's analysis, and `list-check-result-assets` when it needs the trace. It ends with the same `Please fill in all fields.` evidence you found in step 4.

## Next

[Monitor a checkout flow](/guides/monitoring-ecommerce-apps-using-playwright): now that you can debug one, build a full checkout monitor with the Playwright Check Suite and a Browser Check side by side.

## Reference

* [`checkly checks`](/cli/checkly-checks), [`checkly assets`](/cli/checkly-assets), and [`checkly rca`](/cli/checkly-rca)
* [Rocky AI root cause analysis](/resolve/ai-root-cause-analysis/overview)
* [Debugging with AI agents](/learn/playwright/debugging-with-ai-agents)
* [Checkly MCP tools](/ai/mcp-server/tools)
* [Checkly Skills](/ai/skills)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.