{"record":{"id":"47c37fe28a7d8744","repo":"Hmbown/CodeWhale","slug":"native-helper-needs-an-update-for-element-identity","errorCode":null,"errorMessage":"native helper needs an update for element identity validation","messagePattern":"native helper needs an update for element identity validation","errorType":"exception","errorClass":"ExecError","httpStatus":null,"severity":"error","filePath":"crates/tui/plugins/computer-use/src/backends/darwin.mjs","lineNumber":1005,"sourceCode":"    },\n    resolve_element: async ({ app_ref, windowIndex, path: pathArr } = {}) => {\n      const r = await native(\"resolve_element\", { app_ref, windowIndex: windowIndex ?? 0, path: pathArr ?? [] });\n      return { found: !!r?.found, element: r?.element ?? null, reason: r?.reason ?? null };\n    },\n    preview: async ({ enabled = true } = {}) => {\n      state.previewEnabled = enabled;\n      if (!enabled) { stopPreviewLoop(); await quiescePreview(); await native(\"preview_notify\", { enabled: false }); return { enabled: false }; }\n      if (!state.inputApp) throw new ExecError(\"open_application first to choose the preview app\");\n      return updatePreview(true);\n    },\n    screenshot,\n    zoom,\n    left_click: async ({ target, strategy = \"auto\" } = {}) => {\n      if (target?.type !== \"element\" || strategy === \"event\" || strategy === \"app\") return pointerClick(\"left\", target?.x, target?.y, 1, strategy);\n      if (![\"auto\", \"a11y\"].includes(strategy)) throw new ExecError(`strategy must be auto, a11y, app or event (got ${JSON.stringify(strategy)})`);\n      try {\n        assertBoundElement(target);\n        if ((await native(\"input_capabilities\"))?.element_identity !== 1) throw new ExecError(\"native helper needs an update for element identity validation\");\n        const semantic = [\"AXTextField\", \"AXTextArea\", \"AXComboBox\", \"AXRow\", \"AXCell\", \"AXMenuItem\"].includes(target.role);\n        if (semantic) await requireBackgroundActions();\n        const receipt = await native(semantic ? \"click_element\" : \"perform_action\", { target, action: \"AXPress\" });\n        if (!receipt?.action_sent) throw new ExecError(\"element press was not acknowledged\");\n        return { ...receipt, action: receipt.action ?? \"AXPress\", strategy: \"a11y\", pointer_moved: false,\n          element: { role: target.role, label: target.label ?? null }, verified: receipt.verified ?? false, verification_required: \"observation\" };\n      } catch (error) {\n        // An AX frame can cover other controls. Never turn a refused or\n        // ambiguous element press into another element's press or a raw click.\n        error.message += ' — no coordinate fallback was sent; take a fresh screenshot or OCR observation and choose an advertised action or a separate computer';\n        throw error;\n      }\n    },\n    double_click: ({ target } = {}) => pointerClick(\"left\", target?.x, target?.y, 2),\n    triple_click: ({ target } = {}) => pointerClick(\"left\", target?.x, target?.y, 3),\n    right_click: async ({ target } = {}) => {\n      if (target?.type !== \"element\") return pointerClick(\"right\", target?.x, target?.y, 1);\n      assertBoundElement(target);","sourceCodeStart":987,"sourceCodeEnd":1023,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/plugins/computer-use/src/backends/darwin.mjs#L987-L1023","documentation":"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.","triggerScenarios":"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.","commonSituations":"Package upgrade without rebuilding the native helper; a stale cached helper; running a helper built before the element-identity feature landed.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const caps = await native('input_capabilities');\nif (caps?.element_identity !== 1) {\n  throw new Error('native helper lacks element identity validation');\n}\nawait session.left_click({ target: boundElement, strategy: 'a11y' });","typeGuard":"const supportsElementIdentity = (caps) => caps?.element_identity === 1;","tryCatchPattern":"try {\n  await session.left_click({ target: element, strategy: 'a11y' });\n} catch (e) {\n  if (String(e.message).includes('native helper needs an update')) {\n    await reinstallNativeHelper();\n    return session.left_click({ target: element, strategy: 'a11y' });\n  } else throw e;\n}","preventionTips":["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."],"tags":["macos","native-helper","element-identity","version-skew"],"backgroundTag":"missing-dependency","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}