> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stably.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Autofix for Tests

> Stably Autofix maintains your tests in production — triaging failures, fixing code, and proving every fix works with real browser replays.

* <Icon icon="bullseye" /> **Accurate triage** — Compares past and current test run replays side-by-side to pinpoint exactly what changed. Digs into network requests, console logs, and DOM state to find the real root cause — especially effective at eliminating flaky tests.
* <Icon icon="layer-group" /> **Scales to real workloads** — Whether you have 5 failures or 500, Autofix spins up on-demand cloud browsers to validate every fix in parallel. Built for production, not demos.
* <Icon icon="circle-check" /> **Every fix comes with proof** — No vibe-test fixes. Every code change is re-run in a real browser, producing a full replay report with screenshots, traces, and DOM snapshots before anything reaches your codebase.

## Quick Setup

<Tabs>
  <Tab title="Stably CLI">
    Run `stably fix` after any test execution:

    ```bash theme={null}
    stably test || stably fix
    ```

    See the [full CLI guide](/stably-cli/fix) for more details on how to collect the fixed files.
  </Tab>

  <Tab title="Stably Cloud">
    Enable the **Autofix** option when you trigger tests — from the UI, on a schedule, or via API.

    You can also turn it on by default for scheduled runs in your `stably.yaml`:

    ```yaml stably.yaml theme={null}
    schedules:
      my-nightly-run:
        cron: "0 0 * * *"
        autofix: true
    ```
  </Tab>
</Tabs>

That's it. Autofix handles the rest — how fixes are delivered (automatic PR, dashboard diff, or local file changes) depends on the trigger method. See [Ways to Use Autofix](#ways-to-use-autofix) below.

## Ways to Use Autofix

### Automatic (at trigger time)

Enable `autofix: true` as a project default in `stably.yaml`, per-schedule, or pass it when triggering a run via the API or dashboard UI. Autofix runs automatically on Stably Cloud after test failures — no manual step needed.

### On-demand (after any failed run)

After any run completes with failures, the **Autofix tab** on the run details page presents **two options** — choose whichever fits your workflow:

* **Autofix on Cloud** — Click **"Fix with Agent"** to start a cloud agent session. The agent diagnoses failures and generates fixes on Stably infrastructure; at the end you can create a PR (if your [repo is connected](/stably2/bring-your-own-repo)).
* **Auto-heal on your device with CLI** — Copy the ready-to-run `npx stably fix <runId>` command and run it locally. Fixes are applied to your working tree. Review with `git diff`, commit when ready.

This works on any failed run — scheduled, API-triggered, UI-triggered, or CLI-triggered — regardless of whether `autofix` was enabled at trigger time.

<Frame caption="The Autofix tab presents both cloud and CLI options for any failed run">
  <img src="https://mintcdn.com/stablyai/95dOSj0l2zMeEQe-/images/autofix/autofix-tab-options.png?fit=max&auto=format&n=95dOSj0l2zMeEQe-&q=85&s=e5c5aecd6ca803dbe9ad73d8b3dcd2b2" alt="Autofix tab showing Fix with Agent button and CLI command side-by-side" width="1662" height="1026" data-path="images/autofix/autofix-tab-options.png" />
</Frame>

### In CI

Add a `stably fix` step after `stably test` in your pipeline. Results are always uploaded to the dashboard, where you can review diffs and create a PR ([repo connected](/stably2/bring-your-own-repo)). Optionally, add git steps to commit/push directly from CI. See the [CI Integration](/stably-cli/fix#ci-integration) section for examples.

### Comparison

|                          | Automatic (at trigger)                                     | On-demand: Cloud                                                | On-demand: CLI                             | CLI in CI                                                                           |
| ------------------------ | ---------------------------------------------------------- | --------------------------------------------------------------- | ------------------------------------------ | ----------------------------------------------------------------------------------- |
| **Trigger**              | `autofix: true` on schedule/API/UI                         | Click "Fix with Agent" on Autofix tab                           | Copy `stably fix <runId>` from Autofix tab | `stably test \|\| stably fix`                                                       |
| **Runs on**              | Stably cloud                                               | Stably cloud                                                    | Your machine                               | Your CI runner                                                                      |
| **PR creation**          | Automatic ([repo connected](/stably2/bring-your-own-repo)) | From dashboard ([repo connected](/stably2/bring-your-own-repo)) | You commit manually                        | From dashboard ([repo connected](/stably2/bring-your-own-repo)), or git steps in CI |
| **Human trigger needed** | No                                                         | Yes (click button)                                              | Yes (run command)                          | No (wired into pipeline)                                                            |

## What Autofix Can Fix

<Tip>
  Every fix is validated by re-running the test in a real browser. You get a full replay report with screenshots, traces, and DOM snapshots — so you can see proof that the fix actually works before merging.
</Tip>

<AccordionGroup>
  <Accordion title="Tests needs update">
    Your app changed but the tests weren't updated. Autofix updates selectors, rewrites flows, and fixes timing issues to match your current application.

    For example, a checkout flow added a new "Shipping Method" step between address and payment:

    **Before:**

    ```typescript theme={null}
    await page.getByRole('button', { name: 'Continue to Payment' }).click();
    await page.getByLabel('Card number').fill('4242424242424242');
    ```

    **After Autofix:**

    ```typescript theme={null}
    await page.getByRole('button', { name: 'Continue to Shipping' }).click();
    await page.getByLabel('Standard Shipping').check();
    await page.getByRole('button', { name: 'Continue to Payment' }).click();
    await page.getByLabel('Card number').fill('4242424242424242');
    ```
  </Accordion>

  <Accordion title="Actual bug in your app">
    The test caught a real bug in your application code. Autofix can fix the application code directly and open a PR — or flag it for your team to investigate.

    For example, a discount code applies the percentage to the wrong total:

    **Bug in app code (`pricing.ts`):**

    ```typescript theme={null}
    // ❌ Discount applied to subtotal instead of pre-tax total
    const discount = subtotal * discountRate;
    ```

    **After Autofix:**

    ```typescript theme={null}
    // ✅ Discount applied to pre-tax total as expected
    const discount = preTaxTotal * discountRate;
    ```
  </Accordion>

  <Accordion title="Flaky / unstable tests">
    Intermittent failures caused by timing, race conditions, or dynamic content. Autofix adds proper waits, stabilizes selectors, or replaces brittle locators with more resilient approaches.

    For example, a test clicks a button before an API response finishes loading:

    **Before:**

    ```typescript theme={null}
    await page.goto('/dashboard');
    await page.getByRole('button', { name: 'Export' }).click();
    ```

    **After Autofix:**

    ```typescript theme={null}
    await page.goto('/dashboard');
    await page.waitForResponse('**/api/dashboard/stats');
    await page.getByRole('button', { name: 'Export' }).click();
    ```
  </Accordion>
</AccordionGroup>

### How Autofix handles failing locators

When a locator fails, Autofix first tries to find the correct updated locator by navigating through your application in a live browser. It inspects the current page state, identifies what changed, and updates the selector in your test to match the new UI.

If you have your [repo connected](/stably2/bring-your-own-repo), Autofix can also update the `data-testid` in your application code alongside the test selector. You can customize this behavior through your [`STABLY.md`](/core-configuration/stably-md) file (e.g., prefer certain selector strategies, naming conventions).

<Accordion title="Example: Updating a broken locator">
  A button was renamed from "Submit" to "Place Order", causing the test to fail.

  **Before:**

  ```typescript theme={null}
  await page.getByRole('button', { name: 'Submit' }).click();
  ```

  **After Autofix:**

  ```typescript theme={null}
  await page.getByRole('button', { name: 'Place Order' }).click();
  ```
</Accordion>

If no reliable locator can be found — for example, when the element is highly dynamic or lacks stable attributes — Autofix may replace it with an [AI locator](/stably-sdk/ai-locator) (`page.getLocatorsByAI()`) or an [`agent.act()`](/stably-sdk/ai-agent-execute) call that uses natural language instead of brittle selectors.

<Accordion title="Example: Replacing with an AI locator">
  A pricing toggle has no stable selector and changes frequently across redesigns.

  **Before:**

  ```typescript theme={null}
  await page.locator('.pricing-toggle > div:nth-child(2) > button.active').click();
  ```

  **After Autofix:**

  ```typescript theme={null}
  const [annualToggle] = await page.getLocatorsByAI('annual billing toggle button');
  await annualToggle.click();
  ```
</Accordion>

## How It Works

<Steps>
  <Step title="Triage">
    Autofix analyzes all failing tests and groups them by root cause — is it an outdated test, a real bug, or a flaky test? Repeated failures with the same root cause are automatically skipped to save cost.
  </Step>

  <Step title="Fix">
    Each issue gets a targeted fix. Autofix opens a real browser to inspect your live application, understand what changed, and apply the right code changes.

    <Frame caption="AI diagnosis report — root cause, category, and fix applied for each failing test">
      <img src="https://mintcdn.com/stablyai/GHoxOsagovLObbI0/images/autofix/diagnosis-report.png?fit=max&auto=format&n=GHoxOsagovLObbI0&q=85&s=51a888d135cb267fe53e5befeff2bf3d" alt="Autofix diagnosis report showing root cause analysis and applied fixes" width="1674" height="1002" data-path="images/autofix/diagnosis-report.png" />
    </Frame>
  </Step>

  <Step title="Validate in a real browser">
    Every fix is re-run in a real browser to confirm it actually works. You get a full **replay report** with screenshots, traces, and DOM snapshots — proof that the fix is correct before any code is merged.
  </Step>

  <Step title="Deliver fixes">
    A summary report is generated with root causes and code diffs. How fixes reach your codebase depends on the trigger method:

    * **Cloud runs with [connected repo](/stably2/bring-your-own-repo):** A PR/MR is created automatically. Review and merge when ready — Stably does not push to your repo until you merge.
    * **Cloud runs without connected repo:** View diagnosis and code diffs in the dashboard. Apply changes to your codebase manually, or [connect your repo](/stably2/bring-your-own-repo) to enable automatic PRs.
    * **CLI runs:** Fixes are applied to local files. Results are always uploaded to the dashboard — review diffs and create a PR from there ([repo connected](/stably2/bring-your-own-repo)). In CI, you can also add git commit/push/PR steps to your workflow if you prefer.

    <Frame caption="Code diff — review exact changes before merging the PR">
      <img src="https://mintcdn.com/stablyai/GHoxOsagovLObbI0/images/autofix/code-diff.png?fit=max&auto=format&n=GHoxOsagovLObbI0&q=85&s=77f7b1f11f45a76e246bda391ef426ce" alt="Autofix code diff showing test code changes" width="1677" height="998" data-path="images/autofix/code-diff.png" />
    </Frame>
  </Step>
</Steps>

***

## FAQ

<AccordionGroup>
  <Accordion title="Does Stably create a PR automatically?">
    It depends on the trigger method:

    * **Cloud Runner with [connected repo](/stably2/bring-your-own-repo):** Yes, automatically. Connecting your repo is not required for running tests or CLI usage — it's only needed when you want Stably to open PRs/MRs from cloud or dashboard runs.
    * **Cloud Runner without connected repo:** No — view diffs in the dashboard, apply manually.
    * **CLI:** Fixes are applied to your local files and results are uploaded to the dashboard. If your repo is connected, you can create a PR from the dashboard. Otherwise, commit manually or add git steps in CI.
  </Accordion>

  <Accordion title="Do I need to trigger autofix manually?">
    Not always:

    * **`autofix: true` (on schedule, API, or UI trigger)** → fully automatic after failures, no separate trigger needed.
    * **Autofix tab (post-run)** → manual trigger. After any failed run, the Autofix tab offers both **"Fix with Agent"** (cloud) and a ready-to-copy **`stably fix`** CLI command. Pick whichever you prefer.
    * **CLI in CI** → automatic if wired into your pipeline (`stably test || stably fix`).
  </Accordion>

  <Accordion title="Where should I run &#x22;stably fix&#x22;?">
    * Inside a **git repository** — required, since fix tracks changes via git.
    * Usually from the **same directory where you run `stably test`**. For non-standard layouts (monorepos, etc.), use `--cwd` or `--config` to point at the right project.
    * With `STABLY_API_KEY` and `STABLY_PROJECT_ID` env vars set (or use `stably login`).
  </Accordion>

  <Accordion title="Can I run stably fix in each CI matrix/shard job?">
    No. Run fix **once** after all shards complete, on a single machine.

    `stably fix` groups failures by root cause across all tests — running per-shard misses cross-test patterns and may cause conflicts.

    See the [CI Integration](/stably-cli/fix#ci-integration) section in the CLI guide for the correct matrix/sharding pattern.
  </Accordion>

  <Accordion title="Can the CLI access tests created on the web portal?">
    Yes. Set `STABLY_PROJECT_ID` to your web portal project ID — the CLI has access to all its tests and run history.
  </Accordion>

  <Accordion title="What env vars does the fix step need?">
    * **Always:** `STABLY_API_KEY` + `STABLY_PROJECT_ID`.
    * **Plus:** the same env vars your tests need (e.g., `BASE_URL`, test credentials) — fix re-runs tests to validate fixes.
    * Use `--env <name>` to load a named environment from Stably, avoiding secret duplication.
  </Accordion>

  <Accordion title="Can I run &#x22;stably fix&#x22; on any failed run?">
    Yes. Grab the run ID from the dashboard or terminal output and run `stably fix <runId>` from your repo directory. Works for local runs, CI runs, and cloud runs.
  </Accordion>
</AccordionGroup>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Fix Tests (stably fix)" icon="wand-magic-sparkles" href="/stably-cli/fix">
    Full guide on `stably fix` — run ID detection, CI integration, and monitoring
  </Card>

  <Card title="Autofix on Scheduled Runs" icon="clock" href="/run-tests/autofix">
    Enable autofix for scheduled cloud runs
  </Card>

  <Card title="Test Reporter" icon="chart-line" href="/stably/stably-test-reporter">
    View fix reports in the dashboard
  </Card>

  <Card title="STABLY.md" icon="file-lines" href="/core-configuration/stably-md">
    Customize how Autofix behaves with project-level rules
  </Card>
</CardGroup>
