wailsapp/wails · error · Error

Unable to retrieve flag '${key}': ${e}

Error message

Unable to retrieve flag '${key}': ${e}

What it means

StretchBlt copies a rectangle from a source DC into a destination DC, scaling it, and returns FALSE on failure. The w32 wrapper panics with 'StretchBlt failed' on that FALSE. Failure is typically caused by invalid source or destination HDCs, zero/negative extents, or an unsupported combination of rop and color depths (e.g. stretching between DCs of very different formats with certain rop codes). Note StretchBlt also famously succeeds-but-blacks when drivers mishandle it, but the panic path is the explicit FALSE return.

Source

Thrown at v3/internal/runtime/desktop/@wailsio/runtime/src/flags.ts:21

| |	 / /___ _(_) /____
| | /| / / __ `/ / / ___/
| |/ |/ / /_/ / / (__  )
|__/|__/\__,_/_/_/____/
The electron alternative for Go
(c) Lea Anthony 2019-present
*/

/**
 * Retrieves the value associated with the specified key from the flag map.
 *
 * @param key - The key to retrieve the value for.
 * @return The value associated with the specified key.
 */
export function GetFlag(key: string): any {
    try {
        return window._wails.flags[key];
    } catch (e) {
        throw new Error("Unable to retrieve flag '" + key + "': " + e, { cause: e });
    }
}

View on GitHub (pinned to 0e754b1b40)

Solutions

  1. Validate all eight coordinate/extent arguments are sensible (non-negative, non-zero where required) before the call.
  2. Confirm both HDCs are alive at call time and that the source bitmap is still selected and not deleted.
  3. For cross-format stretching, first convert via a compatible DC of the same color depth, or use SetStretchBltMode(COLORONCOLOR) before the call.
  4. Capture GetLastError immediately on failure for the precise code.
  5. Consider GDI+ (w32.GdipDrawImageRectRect) for high-quality scaling if format quirks persist.

Example fix

// before
w32.StretchBlt(hdcDst, 0, 0, -w, -h, hdcSrc, 0, 0, sw, sh, w32.SRCCOPY) // negative extents -> panic

// after
if w > 0 && h > 0 {
	w32.SetStretchBltMode(hdcDst, w32.COLORONCOLOR)
	w32.StretchBlt(hdcDst, 0, 0, w, h, hdcSrc, 0, 0, sw, sh, w32.SRCCOPY)
}
Defensive patterns

Strategy: validation

Validate before calling

func validStretchArgs(dw, dh, sw, sh int) bool {
	return dw > 0 && dh > 0 && sw > 0 && sh > 0
}

Try / catch

defer func() {
	if r := recover(); r != nil {
		if msg, _ := r.(string); strings.HasPrefix(msg, "StretchBlt failed") {
			err = fmt.Errorf("StretchBlt: %v (check DCs and extents)", r)
			return
		}
		panic(r)
	}
}()
w32.StretchBlt(dst, 0, 0, dw, dh, src, 0, 0, sw, sh, w32.SRCCOPY)

Prevention

When it happens

Trigger: Scaling a screenshot or image whose source memory DC/bitmap was already deleted; passing swapped source/dest width-height so extents are negative; using a rop like SRCAND with incompatible surface formats; calling after the capture DC from GetWindowDC was released.

Common situations: Screen-capture or image-resize code in tray/screenshot features; DPI-scaling blits between a 32bpp compatible bitmap and a 16bpp screen DC; race where the frame buffer is destroyed while a render goroutine still blits.

Related errors


AI-assisted analysis of wailsapp/wails@0e754b1b40 (2026-08-15). Data as JSON: /api/errors/1f35373ed6c0d1ff. Report an issue: GitHub.