{"record":{"id":"6850e7eeeac8796c","repo":"affaan-m/ECC","slug":"image-not-found-on-screen-template-path","errorCode":null,"errorMessage":"Image not found on screen: {template_path}","messagePattern":"Image not found on screen: (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"skills/windows-desktop-e2e/SKILL.md","lineNumber":780,"sourceCode":"def find_image_on_screen(template_path, confidence=0.85):\n    \"\"\"Locate a template image on screen. Returns (x, y) center or None.\"\"\"\n    screen   = np.array(pyautogui.screenshot())\n    template = np.array(Image.open(template_path))\n    result   = cv2.matchTemplate(\n        cv2.cvtColor(screen, cv2.COLOR_RGB2BGR),\n        cv2.cvtColor(template, cv2.COLOR_RGB2BGR),\n        cv2.TM_CCOEFF_NORMED,\n    )\n    _, max_val, _, max_loc = cv2.minMaxLoc(result)\n    if max_val >= confidence:\n        h, w = template.shape[:2]\n        return max_loc[0] + w // 2, max_loc[1] + h // 2\n    return None\n\ndef click_image(template_path, confidence=0.85):\n    pos = find_image_on_screen(template_path, confidence)\n    if pos is None:\n        raise RuntimeError(f\"Image not found on screen: {template_path}\")\n    pyautogui.click(*pos)\n```\n\n### DPI / Scaling Rules (screenshot mode only)\n\nScreenshot matching is brutally sensitive to Windows display scaling (100% / 125% / 150%). Three hard rules:\n\n1. **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.\n2. **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.\n3. **Record the scale alongside each artefact.** On capture, write `GetDpiForWindow(hwnd) / 96` to `artifacts/<test>/metadata.json` — postmortems become obvious instead of guess-work.\n\n> 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.\n\n### Debugging Match Confidence\n\nWhen 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.\n\n```python","sourceCodeStart":762,"sourceCodeEnd":798,"githubUrl":"https://github.com/affaan-m/ECC/blob/06c5e118c4d3e6c3b7f9445f973a2194c82de193/skills/windows-desktop-e2e/SKILL.md#L762-L798","documentation":"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.","triggerScenarios":"Triggered when SKILL.md rejects the current invocation: Image not found on screen: <value>","commonSituations":"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.","solutions":["Verify the referenced path, id, or resource exists and is spelled correctly, then retry."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"06c5e118c4d3e6c3b7f9445f973a2194c82de193","analyzedAt":"2026-08-18T11:27:13.915Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}