wailsapp/wails · error · Error

Invalid JSON passed to callback: ${e.message}. Message: ${in

Error message

Invalid JSON passed to callback: ${e.message}. Message: ${incomingMessage}

What it means

PatBlt fills a rectangle on a device context with the currently selected brush using the given raster operation. The w32 wrapper calls gdi32.PatBlt via syscall and panics with 'PatBlt failed' when the API returns 0 (FALSE), which Windows uses to signal failure. The panic discards the real reason; the actual code is only available via GetLastError immediately after the call. Typical causes are an invalid or destroyed HDC, a rectangle with zero/negative extents, or a raster-op code PatBlt does not support.

Source

Thrown at v2/internal/frontend/runtime/desktop/calls.js:167

};


/**
 * Called by the backend to return data to a previously called
 * binding invocation
 *
 * @export
 * @param {string} incomingMessage
 */
export function Callback(incomingMessage) {
	// Parse the message
	let message;
	try {
		message = JSON.parse(incomingMessage);
	} catch (e) {
		const error = `Invalid JSON passed to callback: ${e.message}. Message: ${incomingMessage}`;
		runtime.LogDebug(error);
		throw new Error(error);
	}
	let callbackID = message.callbackid;
	let callbackData = callbacks[callbackID];
	if (!callbackData) {
		const error = `Callback '${callbackID}' not registered!!!`;
		console.error(error); // eslint-disable-line
		throw new Error(error);
	}
	clearTimeout(callbackData.timeoutHandle);

	delete callbacks[callbackID];

	if (message.error) {
		const err = message.error instanceof Error ? message.error : new Error(message.error);
		callbackData.reject(err);
	} else {
		callbackData.resolve(message.result);
	}

View on GitHub (pinned to 0e754b1b40)

Solutions

  1. Verify the HDC is still valid and not double-released: every GetDC must have a matching ReleaseDC and every BeginPaint an EndPaint before any PatBlt call.
  2. Use only rop codes PatBlt supports: PATCOPY, PATINVERT, DSTINVERT, BLACKNESS, WHITENESS.
  3. Check width/height are positive before calling; compute them from window client rects that can be zero during minimize.
  4. Immediately after a failure, capture w32.GetLastError() (or set a breakpoint on the panic and inspect errno from the lazy syscall call) to identify the exact GDI error such as ERROR_INVALID_HANDLE.
  5. If the panic aborts the app at shutdown, gate painting behind a 'window is closing' check so draw code stops before the DC dies.

Example fix

// before
w32.PatBlt(hdc, 0, 0, width, height, w32.SRCCOPY) // unsupported rop -> panic

// after
w32.PatBlt(hdc, 0, 0, width, height, w32.PATCOPY) // PatBlt-supported rop
if width <= 0 || height <= 0 {
	return // nothing to fill
}
Defensive patterns

Strategy: validation

Validate before calling

func canPatBlt(hdc w32.HDC, w, h int, rop uint) bool {
	if hdc == 0 || w <= 0 || h <= 0 {
		return false
	}
	switch rop {
	case w32.PATCOPY, w32.PATINVERT, w32.DSTINVERT, w32.BLACKNESS, w32.WHITENESS:
		return true
	}
	return false
}

Try / catch

defer func() {
	if r := recover(); r != nil {
		if msg, ok := r.(string); ok && strings.HasPrefix(msg, "PatBlt failed") {
			log.Printf("paint fill skipped: %v (lasterr=%d)", r, w32.GetLastError())
			return
		}
		panic(r)
	}
}()
w32.PatBlt(hdc, 0, 0, w, h, w32.PATCOPY)

Prevention

When it happens

Trigger: Calling w32.PatBlt with an HDC that was deleted via DeleteDC, using a dwRop other than PATCOPY, PATINVERT, DSTINVERT, BLACKNESS, or WHITENESS (PatBlt rejects SRCCOPY-style rop codes), passing zero width/height, or filling on a DC whose selected brush was deleted while still selected.

Common situations: Drawing background rects in a custom-paint path during window teardown when the paint DC is already released; porting code from BitBlt and reusing an incompatible rop constant; intermixing w32 direct calls with another framework that owns and disposes the DC.

Understand the failure class

Related errors


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