affaan-m/ECC · error · RuntimeError

Image not found on screen

Error message

Image not found on screen: {template_path}

What it means

Template-matching helper in the Windows E2E skill: cv2.matchTemplate's best score stayed below the confidence threshold, so the template image was not found on screen. The skill's guidance is to treat this as a scaling/DPI mismatch before assuming absence.

Solutions

  1. Verify the referenced path, id, or resource exists and is spelled correctly, then retry.
Defensive patterns

Strategy: fallback

When it happens

Trigger: Triggered when SKILL.md rejects the current invocation: Image not found on screen: <value>

Common situations: Occurs while running skills/windows-desktop-e2e/SKILL.md with invalid arguments, missing flags, or a failing external dependency; the guard at skills/windows-desktop-e2e/SKILL.md:780 aborts the command with this message.


AI-assisted analysis of affaan-m/ECC@06c5e118c4 (2026-08-18). Data as JSON: /api/errors/6850e7eeeac8796c. Report an issue: GitHub.

Appendix: source

Thrown at skills/windows-desktop-e2e/SKILL.md:780

def find_image_on_screen(template_path, confidence=0.85):
    """Locate a template image on screen. Returns (x, y) center or None."""
    screen   = np.array(pyautogui.screenshot())
    template = np.array(Image.open(template_path))
    result   = cv2.matchTemplate(
        cv2.cvtColor(screen, cv2.COLOR_RGB2BGR),
        cv2.cvtColor(template, cv2.COLOR_RGB2BGR),
        cv2.TM_CCOEFF_NORMED,
    )
    _, max_val, _, max_loc = cv2.minMaxLoc(result)
    if max_val >= confidence:
        h, w = template.shape[:2]
        return max_loc[0] + w // 2, max_loc[1] + h // 2
    return None

def click_image(template_path, confidence=0.85):
    pos = find_image_on_screen(template_path, confidence)
    if pos is None:
        raise RuntimeError(f"Image not found on screen: {template_path}")
    pyautogui.click(*pos)
```

### DPI / Scaling Rules (screenshot mode only)

Screenshot matching is brutally sensitive to Windows display scaling (100% / 125% / 150%). Three hard rules:

1. **Capture templates at the same scale as the target machine.** Don't try to rescue a mismatch with `PIL.Image.resize` — `cv2.matchTemplate` is very fragile against resampling artefacts.
2. **Pin the CI display scaling.** On `windows-latest` add a step like `Set-DisplayResolution 1920 1080 -Force` and disable per-monitor DPI scaling, so screenshot dimensions are reproducible.
3. **Record the scale alongside each artefact.** On capture, write `GetDpiForWindow(hwnd) / 96` to `artifacts/<test>/metadata.json` — postmortems become obvious instead of guess-work.

> Process-level DPI awareness (`SetProcessDpiAwarenessContext`) **can conflict with Qt's own DPI handling** when the app under test is Qt-based. Prefer "same-scale templates + CI pin" over flipping process-wide DPI mode in fixtures.

### Debugging Match Confidence

When tuning the `confidence` threshold, the only sane workflow is to **see** where the match landed. The helper below is diagnosis-only — do not call it from test code.

```python

View on GitHub (pinned to 06c5e118c4)