{"record":{"id":"93e937071e35ad0e","repo":"Hmbown/CodeWhale","slug":"xdotool-args-0-exited-r-code-r-stderr-trim-slice-0-200","errorCode":null,"errorMessage":"xdotool ${args[0]} exited ${r.code}: ${r.stderr.trim().slice(0, 200)}","messagePattern":"xdotool (.+?) exited (.+?): (.+?)","errorType":"exception","errorClass":"ExecError","httpStatus":null,"severity":"error","filePath":"crates/tui/plugins/computer-use/src/backends/linux.mjs","lineNumber":155,"sourceCode":"      args.push(file);\n    } else {\n      if (region) args.push(\"-crop\", `${Math.round(region[2])}x${Math.round(region[3])}+${Math.round(region[0])}+${Math.round(region[1])}`);\n      args.push(file);\n    }\n    const r = await run(cmd, args, { timeoutMs: 10_000 });\n    if (r.code !== 0) throw new ExecError(`${cmd} exited ${r.code}: ${r.stderr.trim().slice(0, 300)}`, r);\n  }\n\n  function recordingsDir() {\n    return path.resolve(process.env.CODEWHALE_CU_RECORDINGS_DIR || path.join(os.homedir(), \".codewhale-cu\", \"recordings\"));\n  }\n\n  async function xdotool(args, opts = {}) {\n    need(\"xdotool\", \"input on X11\");\n    throwIfAborted();\n    const r = await run(\"xdotool\", args, opts);\n    throwIfAborted();\n    if (r.code !== 0) throw new ExecError(`xdotool ${args[0]} exited ${r.code}: ${r.stderr.trim().slice(0, 200)}`, r);\n    return r.stdout.trim();\n  }\n\n  async function ydotool(args, opts = {}) {\n    need(\"ydotool\", \"input on Wayland (ydotool needs its daemon running: sudo ydotoold)\");\n    throwIfAborted();\n    const r = await run(\"ydotool\", args, opts);\n    throwIfAborted();\n    if (r.code !== 0) throw new ExecError(`ydotool exited ${r.code}: ${r.stderr.trim().slice(0, 200)}`, r);\n    return r.stdout.trim();\n  }\n\n  function xdotoolKey(text) {\n    return String(text).split(\"+\").map((p) => {\n      const k = p.trim().toLowerCase();\n      if (XKEYS[k]) return XKEYS[k];\n      if (/^f\\d{1,2}$/.test(k)) return k.toUpperCase();\n      return p.trim(); // pass through names already in xdotool form","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/plugins/computer-use/src/backends/linux.mjs#L137-L173","documentation":"Thrown by the xdotool wrapper when the xdotool subprocess exits non-zero on X11. The message includes the first xdotool subcommand (args[0], e.g. key, mousemove, click) plus up to 200 chars of stderr. The wrapper first verifies xdotool exists via `need`, so this error means xdotool ran but rejected the request.","triggerScenarios":"Any input action (key, type, click, move) routed through xdotool(args, opts) on X11 where xdotool exits non-zero: unknown keysym, no X display/authority, window target disappeared, or malformed coordinate arguments.","commonSituations":"SSH/headless X11 without DISPLAY set; X SECURITY blocking the connection; sending a key name xdotool doesn't recognize (e.g. 'meta' instead of mapping it); clicking a window that closed between lookup and action.","solutions":["Read the stderr in the message; xdotool errors usually name the bad keysym or 'Can't open display'.","Ensure DISPLAY and XAUTHORITY are correct for the target X server (`xdotool getactivewindow` as a smoke test).","Normalize modifier/key names before calling: this backend maps meta->logo only in waylandKey, so pass xdotool-valid names like 'ctrl', 'alt', 'super'.","Re-resolve the target window id if you passed one; the window may have closed.","If on Wayland, ensure the session probe picked the right backend (ydotool/wtype) rather than xdotool."],"exampleFix":"// before\nawait xdotool(['key', 'Meta_L']);\n// after\nawait xdotool(['key', 'super']);","handlingStrategy":"try-catch","validationCode":"async function xdotoolReady() {\n  try {\n    await run('xdotool', ['getdisplaygeometry'], { timeoutMs: 5000 });\n    return true;\n  } catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await xdotool(['key', name]);\n} catch (e) {\n  if (e instanceof ExecError && e.message.startsWith('xdotool')) {\n    if (/Can't open display/.test(e.message)) fixDisplayEnv();\n    else if (/window.*invalid|Unknown window/i.test(e.message)) await refreshWindowTarget();\n    else console.error('xdotool rejected:', e.message);\n  } else throw e;\n}","preventionTips":["Run `xdotool getdisplaygeometry` as a preflight in the target session.","Use xdotool-valid key names (keysyms); map app shortcut names before passing.","Keep DISPLAY/XAUTHORITY set for the invoking user.","Re-resolve window ids just before interacting; windows close asynchronously.","On Wayland, make sure the session probe routes input away from xdotool."],"tags":["subprocess","xdotool","x11","input"],"backgroundTag":"external-command-failed","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"}