{"record":{"id":"92559b527a961c54","repo":"Hmbown/CodeWhale","slug":"strategy-must-be-auto-a11y-app-or-event-got-json-stringify","errorCode":null,"errorMessage":"strategy must be auto, a11y, app or event (got ${JSON.stringify(strategy)})","messagePattern":"strategy must be auto, a11y, app or event \\(got (.+?)\\)","errorType":"exception","errorClass":"ExecError","httpStatus":null,"severity":"error","filePath":"crates/tui/plugins/computer-use/src/backends/darwin.mjs","lineNumber":422,"sourceCode":"    const b = buttonCode(button);\n    const steps = [{ type: MOUSE_MOVED, x, y, button: b, clickState: 0 }];\n    for (let i = 1; i <= clicks; i++) {\n      steps.push({ type: m.down, x, y, button: b, clickState: i });\n      steps.push({ type: m.up, x, y, button: b, clickState: i });\n    }\n    return steps;\n  }\n\n  /**\n   * Coordinate pointer click. A left single click is first hit-tested against\n   * the bound application's accessibility tree: when the point names a\n   * pressable element we perform its semantic action, which needs no pointer\n   * and no foreground. strategy=\"a11y\" requires that and fails closed;\n   * strategy=\"event\" goes straight to the guarded global gesture.\n   */\n  async function pointerClick(button, x, y, clicks, strategy = \"auto\") {\n    assertInScreen(x, y);\n    if (![\"auto\", \"a11y\", \"event\", \"app\"].includes(strategy)) throw new ExecError(`strategy must be auto, a11y, app or event (got ${JSON.stringify(strategy)})`);\n    let a11yReason = null;\n    if (strategy !== \"event\" && [\"left\", \"right\"].includes(button) && clicks === 1) {\n      if (button === \"right\") await requireBackgroundActions();\n      const hit = await native(\"hit_test\", { x, y, perform: true, ...(button === \"right\" ? { operation: \"context\" } : {}) });\n      if (hit?.action_sent) {\n        return { action_sent: true, strategy: \"a11y\", action: hit.action, pointer_moved: false, at: { x, y }, button, clicks,\n                 element: { role: hit.element?.role ?? null, label: hit.element?.label ?? null } };\n      }\n      a11yReason = hit?.reason ?? \"not_found\";\n      if (strategy === \"a11y\") {\n        throw new ExecError(`no supported accessibility click at (${x}, ${y}) in the bound application (${a11yReason}) — observe the available actions, use strategy \"app\" for a window-scoped pointer click, or a separate computer`);\n      }\n    } else if (strategy === \"a11y\") {\n      throw new ExecError(`strategy \"a11y\" is only available for a left single click on this backend; ${mouseName(button)} x${clicks} has no accessibility equivalent`);\n    }\n    if (strategy === \"app\" || (strategy === \"auto\" && !state.foregroundInput)) {\n      // Window-routed record delivery: AppKit accepts the events as genuine\n      // input, the cursor never moves. A momentary no-raise front lease is","sourceCodeStart":404,"sourceCodeEnd":440,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/plugins/computer-use/src/backends/darwin.mjs#L404-L440","documentation":"pointerClick validates the strategy argument against the closed set {auto, a11y, app, event} before doing any work. Any other string (or non-string serialized to JSON) is rejected immediately so an unknown strategy never silently degrades to a default path.","triggerScenarios":"Passing a strategy value other than the four allowed ones, e.g. 'click', 'press', 'semantic', 'Auto' (case-sensitive), a truncated/typo'd value, or JSON-serialized input where the field was misnamed.","commonSituations":"LLM/model-generated tool arguments inventing a strategy name; a caller upgrading from an older backend that accepted different keywords; config-driven clicks where the strategy came from user configuration.","solutions":["Use one of the exact values: auto, a11y, app or event (lowercase)","Default to 'auto' and let the backend choose a11y vs window-record delivery","Validate/normalize the strategy value at the call site before invoking pointerClick","If you need a strategy that does not exist, express it via existing primitives (a11y hit_test for semantic actions, event for raw gestures)"],"exampleFix":"// before\nawait click(x, y, { strategy: \"semantic\" });\n// after\nawait click(x, y, { strategy: \"a11y\" });","handlingStrategy":"validation","validationCode":"const STRATEGIES = [\"auto\", \"a11y\", \"app\", \"event\"];\nif (!STRATEGIES.includes(strategy)) throw new Error(`strategy must be one of ${STRATEGIES.join(\", \")}`);","typeGuard":"const isStrategy = (s) => typeof s === \"string\" && [\"auto\", \"a11y\", \"app\", \"event\"].includes(s);","tryCatchPattern":null,"preventionTips":["Default to 'auto' unless you specifically need to force a path","Keep the allowed values in a shared constant with your tool schema/enum","Validate LLM-generated arguments against the enum before calling"],"tags":["validation","invalid-enum-value","argument"],"backgroundTag":"invalid-enum-value","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}