> For the complete documentation index, see [llms.txt](https://docs.duku.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.duku.ai/core-concepts/visual-issues.md).

# Visual issues

Catch bugs your users can see on screen, even when no error is raised.

Some bugs never raise an error. A basket total that does not match its items, an invoice marked both paid and overdue, a greeting that reads "Hello {first\_name}" - the page loads, every request succeeds, and the problem is only visible on the screen.

Duku looks at the screens it captures while it explores your app and reports these as **visual issues**, alongside the errors it already finds.

#### <i class="fa-camera">:camera:</i> What Duku looks at

* Every distinct screen an exploration reaches
* The screen after a form is saved or a request is refused, to check what the user was told
* All the screens from one run together, to catch details that disagree between pages

#### <i class="fa-list-check">:list-check:</i> What gets reported

| Type                               | What it means                                                                | Example                                                  |
| ---------------------------------- | ---------------------------------------------------------------------------- | -------------------------------------------------------- |
| **Inconsistent value**             | Two figures or details about the same thing disagree                         | A basket lists 3 items while its badge says 2            |
| **Inconsistent state**             | Something is shown in two states that cannot both be true                    | An invoice marked both Paid and Overdue                  |
| **Unexpected error**               | The page shows an error message, crash or error page a user should never see | "Something went wrong" in place of a report              |
| **Corrupted text**                 | Text is garbled, broken or shows unfilled template code                      | A reply that ends "Dear {name},"                         |
| **Untranslated text**              | Text is in the wrong language for the page                                   | An English button on a French checkout                   |
| **Action failed**                  | Something a user expects to work ends in an error                            | Saving a profile opens an error page                     |
| **Rendering differs across pages** | The same element shows correctly on one page and broken on another           | A price shown on the product page is blank in the basket |

#### <i class="fa-network-wired">:network-wired:</i> Failed requests your app handled

With visual issues on, Duku also uses the screen to judge failed requests.

* When your app refuses a request and the screen explains why in its own words - "Your basket is empty", "This item is out of stock" - or the page loads normally regardless, the failed request stays out of your Issues list, pull request comments and notifications. It is still listed on the run.
* When a save fails without telling the user, or the screen says it worked when it did not, the issue is raised to **High** priority.
* A failure the screen does not explain is reported as usual.

A status you set yourself always wins.

#### <i class="fa-magnifying-glass">:magnifying-glass:</i> Where you see them

On the Issues page, a camera marker after the title marks a visual issue. To see only visual issues, open the filter in the **Issue** column header and select **Visual issues**.

Open a visual issue to see the screenshot it was found on, with a short description of what is wrong, the page, when it was captured and the run. Select **Open full size** to enlarge it, step through other examples of the same problem, or select **View run** to open the run. Any other signals behind the same issue are listed under [Issues & signals](/core-concepts/issues-and-signals.md).

Visual issues also appear on the run they were found in, with the run's other errors.

#### <i class="fa-arrows-split-up-and-left">:arrows-split-up-and-left:</i> Working with visual issues

Visual issues work like every other issue:

* Set their status and priority from the Issues list or the issue page.
* An issue you set to **Ignored** stays ignored when later runs find it again.
* File them to Linear and get them in Slack and webhooks. Tickets and messages carry the title and description.
* On pull requests, the comment and the GitHub check run list them with the other new issues.
* They arrive through the Issues API in the same query as every other issue, with the category `VISUAL_ERROR`. What is wrong is in the issue's title and description, and in each signal's `sampleError.message`.
