Hmbown/CodeWhale · error · ExecError
native helper needs an update for element identity…
Error message
native helper needs an update for element identity validation
What it means
Inside the a11y click path, after assertBoundElement passes, the backend asks the native helper for input_capabilities and requires element_identity === 1 — proof that the helper can validate that a stored element reference still maps to the same UI element before pressing it. An older native helper without element-identity support cannot offer that safety, so the backend refuses rather than clicking a possibly-stale target.
Solutions
- Rebuild/reinstall the native macOS helper to match the plugin version that declares element_identity support.
- Verify with input_capabilities that element_identity === 1 before retrying the click.
- Clear cached helper binaries so the current version is launched.
- Temporarily fall back to a coordinate/event strategy (e.g. pointerClick with strategy 'event') if stale-element risk is acceptable.
Defensive patterns
Strategy: validation
Validate before calling
const caps = await native('input_capabilities');
if (caps?.element_identity !== 1) {
throw new Error('native helper lacks element identity validation');
}
await session.left_click({ target: boundElement, strategy: 'a11y' }); Type guard
const supportsElementIdentity = (caps) => caps?.element_identity === 1;
Try / catch
try {
await session.left_click({ target: element, strategy: 'a11y' });
} catch (e) {
if (String(e.message).includes('native helper needs an update')) {
await reinstallNativeHelper();
return session.left_click({ target: element, strategy: 'a11y' });
} else throw e;
} Prevention
- Keep the native helper in lockstep with the plugin version; rebuild on every upgrade.
- Check input_capabilities (element_identity, window_ocr) once per session and surface mismatches early.
- Avoid distributing prebuilt sessions that assume helper features without a capability probe.
When it happens
Trigger: left_click (or the sibling element-action paths) with a bound element target on macOS when the installed native helper's input_capabilities.element_identity is not 1 — outdated helper binary or version mismatch with the JS plugin.
Common situations: Package upgrade without rebuilding the native helper; a stale cached helper; running a helper built before the element-identity feature landed.
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- The native helper needs an update for selected-window text…
- application not found — call list_apps for exact names/pids
- background preview capture failed
- choose one available display for recording
- continual harness state
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/47c37fe28a7d8744.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/plugins/computer-use/src/backends/darwin.mjs:1005
},
resolve_element: async ({ app_ref, windowIndex, path: pathArr } = {}) => {
const r = await native("resolve_element", { app_ref, windowIndex: windowIndex ?? 0, path: pathArr ?? [] });
return { found: !!r?.found, element: r?.element ?? null, reason: r?.reason ?? null };
},
preview: async ({ enabled = true } = {}) => {
state.previewEnabled = enabled;
if (!enabled) { stopPreviewLoop(); await quiescePreview(); await native("preview_notify", { enabled: false }); return { enabled: false }; }
if (!state.inputApp) throw new ExecError("open_application first to choose the preview app");
return updatePreview(true);
},
screenshot,
zoom,
left_click: async ({ target, strategy = "auto" } = {}) => {
if (target?.type !== "element" || strategy === "event" || strategy === "app") return pointerClick("left", target?.x, target?.y, 1, strategy);
if (!["auto", "a11y"].includes(strategy)) throw new ExecError(`strategy must be auto, a11y, app or event (got ${JSON.stringify(strategy)})`);
try {
assertBoundElement(target);
if ((await native("input_capabilities"))?.element_identity !== 1) throw new ExecError("native helper needs an update for element identity validation");
const semantic = ["AXTextField", "AXTextArea", "AXComboBox", "AXRow", "AXCell", "AXMenuItem"].includes(target.role);
if (semantic) await requireBackgroundActions();
const receipt = await native(semantic ? "click_element" : "perform_action", { target, action: "AXPress" });
if (!receipt?.action_sent) throw new ExecError("element press was not acknowledged");
return { ...receipt, action: receipt.action ?? "AXPress", strategy: "a11y", pointer_moved: false,
element: { role: target.role, label: target.label ?? null }, verified: receipt.verified ?? false, verification_required: "observation" };
} catch (error) {
// An AX frame can cover other controls. Never turn a refused or
// ambiguous element press into another element's press or a raw click.
error.message += ' — no coordinate fallback was sent; take a fresh screenshot or OCR observation and choose an advertised action or a separate computer';
throw error;
}
},
double_click: ({ target } = {}) => pointerClick("left", target?.x, target?.y, 2),
triple_click: ({ target } = {}) => pointerClick("left", target?.x, target?.y, 3),
right_click: async ({ target } = {}) => {
if (target?.type !== "element") return pointerClick("right", target?.x, target?.y, 1);
assertBoundElement(target);View on GitHub (pinned to 73e0f67d83)