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
- 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.
```pythonView on GitHub (pinned to 06c5e118c4)