affaan-m/ECC · error · RuntimeError
Template unreadable
Error message
Template unreadable: {template_path} What it means
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'.
Solutions
- Review the constraint in the error message, correct the input accordingly, and re-run.
Defensive patterns
Strategy: validation
When it happens
Trigger: Triggered when SKILL.md rejects the current invocation: Template unreadable: <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:808 aborts the command with this message.
AI-assisted analysis of affaan-m/ECC@06c5e118c4 (2026-08-18).
Data as JSON: /api/errors/a1b9d1f903abf402.
Report an issue: GitHub.
Appendix: source
Thrown at skills/windows-desktop-e2e/SKILL.md:808
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
def debug_match(template_path, out="artifacts/match_debug.png", confidence=0.85):
"""Diagnosis-only. Draw the best-match rectangle + score back on the current screen.
NOT for production tests — use when calibrating confidence or chasing false matches.
"""
import os, cv2, pyautogui, numpy as np
screen = np.array(pyautogui.screenshot())[:, :, ::-1]
tpl = cv2.imread(template_path)
if tpl is None:
raise RuntimeError(f"Template unreadable: {template_path}")
res = cv2.matchTemplate(screen, tpl, cv2.TM_CCOEFF_NORMED)
_, mv, _, ml = cv2.minMaxLoc(res)
h, w = tpl.shape[:2]
colour = (0, 255, 0) if mv >= confidence else (0, 0, 255) # green pass / red fail
cv2.rectangle(screen, ml, (ml[0]+w, ml[1]+h), colour, 2)
cv2.putText(screen, f"score={mv:.3f} thr={confidence}",
(ml[0], max(20, ml[1]-6)),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, colour, 2)
os.makedirs(os.path.dirname(out) or ".", exist_ok=True)
cv2.imwrite(out, screen)
return mv
```
**Use sparingly** — image matching breaks on DPI changes, theme switches, and partial occlusion.
Always try UIA first; fall back to screenshots only for genuinely unreachable controls.
## Anti-Patterns
View on GitHub (pinned to 06c5e118c4)