{"record":{"id":"a1b9d1f903abf402","repo":"affaan-m/ECC","slug":"template-unreadable-template-path","errorCode":null,"errorMessage":"Template unreadable: {template_path}","messagePattern":"Template unreadable: (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"skills/windows-desktop-e2e/SKILL.md","lineNumber":808,"sourceCode":"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.\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\ndef debug_match(template_path, out=\"artifacts/match_debug.png\", confidence=0.85):\n    \"\"\"Diagnosis-only. Draw the best-match rectangle + score back on the current screen.\n\n    NOT for production tests — use when calibrating confidence or chasing false matches.\n    \"\"\"\n    import os, cv2, pyautogui, numpy as np\n    screen = np.array(pyautogui.screenshot())[:, :, ::-1]\n    tpl    = cv2.imread(template_path)\n    if tpl is None:\n        raise RuntimeError(f\"Template unreadable: {template_path}\")\n    res    = cv2.matchTemplate(screen, tpl, cv2.TM_CCOEFF_NORMED)\n    _, mv, _, ml = cv2.minMaxLoc(res)\n    h, w   = tpl.shape[:2]\n    colour = (0, 255, 0) if mv >= confidence else (0, 0, 255)  # green pass / red fail\n    cv2.rectangle(screen, ml, (ml[0]+w, ml[1]+h), colour, 2)\n    cv2.putText(screen, f\"score={mv:.3f} thr={confidence}\",\n                (ml[0], max(20, ml[1]-6)),\n                cv2.FONT_HERSHEY_SIMPLEX, 0.7, colour, 2)\n    os.makedirs(os.path.dirname(out) or \".\", exist_ok=True)\n    cv2.imwrite(out, screen)\n    return mv\n```\n\n**Use sparingly** — image matching breaks on DPI changes, theme switches, and partial occlusion.\nAlways try UIA first; fall back to screenshots only for genuinely unreachable controls.\n\n## Anti-Patterns\n","sourceCodeStart":790,"sourceCodeEnd":826,"githubUrl":"https://github.com/affaan-m/ECC/blob/06c5e118c4d3e6c3b7f9445f973a2194c82de193/skills/windows-desktop-e2e/SKILL.md#L790-L826","documentation":"Diagnosis helper in the Windows E2E skill: the template image file itself could not be read (missing, wrong path, or unsupported format), so no match can be attempted — distinct from 'image not found on screen'.","triggerScenarios":"Triggered when SKILL.md rejects the current invocation: Template unreadable: <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:808 aborts the command with this message.","solutions":["Review the constraint in the error message, correct the input accordingly, and re-run."],"exampleFix":null,"handlingStrategy":"validation","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"}