Hmbown/CodeWhale · error · ExecError
strategy " " is macOS-only; this backend dispatches…
Error message
strategy "${strategy}" is macOS-only; this backend dispatches coordinate clicks as raw pointer events — use an element target for a semantic action What it means
assertEventStrategy enforces that this Windows backend only dispatches coordinate clicks as raw pointer events. Requesting strategy values reserved for the macOS accessibility backend (anything besides null, "auto", or "event") fails closed with this ExecError instead of silently degrading accessibility strategies into raw clicks.
Solutions
- Remove the strategy option or set it to "auto"/"event" for coordinate clicks on Windows
- Use an element target (semantic/accessibility locator) if you need accessibility-driven actions
- Gate strategy selection by platform in shared code instead of passing one global value
Example fix
// before
await click({ x: 100, y: 200, strategy: "a11y" });
// after
await click({ x: 100, y: 200, strategy: "auto" }); // or use an element target for semantic action Defensive patterns
Strategy: validation
Validate before calling
const allowed = new Set([null, 'auto', 'event']);
if (!allowed.has(strategy)) throw new SkipError(`strategy "${strategy}" unsupported on win32`); Type guard
const isWin32ClickStrategy = (s) => s == null || s === 'auto' || s === 'event';
Prevention
- Select strategies per-platform, never as a global config value
- Default to 'auto' and let the backend resolve strategy
- Use element targets when you need semantic/accessibility actions
When it happens
Trigger: Calling click/tap with { strategy: "a11y" } (or any non-auto/event value) while targeting coordinate-based input on the win32 backend.
Common situations: Shared automation code written for macOS ported to Windows; a config file that sets a global click strategy; agents selecting "a11y" heuristically for all platforms.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Android dladdr could not locate the updater's loaded image
- Android dladdr returned an empty loaded-image path
- application not found or name is ambiguous in the AT-SPI…
- AT-SPI action failed
- AT-SPI resolve failed
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/4d3bfaa10ee8f05c.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/plugins/computer-use/src/backends/win32.mjs:116
using System.Windows.Automation;
public static class CUAutomationProviders {
public static void Register() {
var assembly = typeof(AutomationElement).Assembly.GetName();
assembly.Name = "UIAutomationClientsideProviders";
// Legacy .NET clears its one-time default-proxy flag before walking a
// dynamic PowerShell stack, which can throw NullReferenceException.
// Retry only registration (no UI action); a second failure propagates.
try { ClientSettings.RegisterClientSideProviderAssembly(assembly); }
catch (System.NullReferenceException) { ClientSettings.RegisterClientSideProviderAssembly(assembly); }
}
}
'@;
[CUAutomationProviders]::Register();`;
/** Coordinate clicks on this backend are always raw pointer events; strategy="a11y" must fail closed rather than silently degrade. */
function assertEventStrategy(strategy) {
if (strategy != null && strategy !== "auto" && strategy !== "event") {
throw new ExecError(`strategy "${strategy}" is macOS-only; this backend dispatches coordinate clicks as raw pointer events — use an element target for a semantic action`);
}
}
function unsupportedSelector(message) {
return Object.assign(new ExecError(message), { code: "unsupported_selector" });
}
// A cached child path alone is unsafe: sibling/window order can change.
// Runtime IDs bind both the root and leaf to the observation that supplied them.
function elementScript(target) {
const ids = [target?.runtime_id, target?.window_runtime_id];
if (ids.some(id => !Array.isArray(id) || !id.length || !id.every(Number.isInteger))
|| !Array.isArray(target?.path) || target.path[0] !== 0 || !target.path.every(i => Number.isInteger(i) && i >= 0)
|| (target.windowIndex != null && target.windowIndex !== 0) || Object.hasOwn(target, "window_id")) {
throw unsupportedSelector("Windows semantic actions require a fresh observed element with window and element runtime identities");
}
const encoded = Buffer.from(JSON.stringify(target), "utf16le").toString("base64");
return `${UIA_PRELUDE}View on GitHub (pinned to 73e0f67d83)