{"record":{"id":"bdae6ec77c0a9aa7","repo":"Hmbown/CodeWhale","slug":"application-not-found-or-name-is-ambiguous-in-the-at-spi","errorCode":null,"errorMessage":"application not found or name is ambiguous in the AT-SPI tree — use a unique exact app_ref.name","messagePattern":"application not found or name is ambiguous in the AT-SPI tree — use a unique exact app_ref\\.name","errorType":"exception","errorClass":"ExecError","httpStatus":null,"severity":"error","filePath":"crates/tui/plugins/computer-use/src/backends/linux.mjs","lineNumber":493,"sourceCode":"        } catch { /* no session/tools — the launch itself is still fine */ }\n      }\n      spawnDetached(target, urlArg ? [urlArg] : [], \"\", true);\n      await new Promise((r) => setTimeout(r, 500));\n      let focusRestored = false;\n      if (prevWindow) {\n        try {\n          focusRestored = (await run(\"xdotool\", [\"windowactivate\", prevWindow], { timeoutMs: 3_000 })).code === 0;\n        } catch { /* best-effort */ }\n      }\n      return { launched: true, name: target, url: urlArg ?? null, activate: activate === true, ...(activate === true ? {} : { focus_restored: focusRestored }) };\n    },\n    get_app_state: async ({ app_ref, window_id } = {}) => {\n      const name = appName(app_ref);\n      if (window_id !== undefined) throw Object.assign(new ExecError(\"Linux app-state window_id selection is unavailable\"), { code: \"unsupported_selector\" });\n      const t = await run(\"python3\", [\"-c\", PYATSPI_WALK, name, \"10\", \"500\"], { timeoutMs: 45_000 }).then((r) =>\n        tryJson((r.stdout.trim().split(\"\\n\").pop() ?? \"\"), null));\n      if (!t) throw new ExecError(\"AT-SPI walk failed — is python3-pyatspi installed and the desktop running an accessibility bus (AT_SPI_BUS)?\");\n      if (!t.found) throw new ExecError(\"application not found or name is ambiguous in the AT-SPI tree — use a unique exact app_ref.name\");\n      return t;\n    },\n    screenshot: async (args = {}) => {\n      rejectWindowSelectors(args);\n      const { display, region, path: outPath } = args;\n      if (outPath != null) outputPath(outPath);\n      await probeSession();\n      const dir = recordingsDir();\n      fs.mkdirSync(dir, { recursive: true });\n      const file = outPath || path.join(dir, `shot-${new Date().toISOString().replace(/[:.]/g, \"-\")}-${crypto.randomBytes(3).toString(\"hex\")}.png`);\n      await takeShot(file, region);\n      const dims = pngSize(file);\n      lastRaster = {\n        file,\n        bytes: fs.statSync(file).size,\n        // Region rasters describe the region; full shots get geometry from the\n        // PNG itself (Linux shots are always scale 1: points == pixels).\n        points: region ? { x: region[0], y: region[1], w: region[2], h: region[3] } : dims ? { x: 0, y: 0, w: dims.w, h: dims.h } : null,","sourceCodeStart":475,"sourceCodeEnd":511,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/plugins/computer-use/src/backends/linux.mjs#L475-L511","documentation":"The pyatspi walk completed and returned JSON, but reported found=false: no application matched app_ref.name exactly (or the name matched more than one application ambiguously) in the AT-SPI tree. The library refuses to guess which application was meant.","triggerScenarios":"app_ref.name does not equal the accessibility application name (e.g. 'chrome' vs 'Google-chrome'); passing a window title or process name instead of the AT-SPI application name; the target app exposes no accessibility (Electron apps without accessibility enabled, Java apps without the java-atk wrapper); multiple windows/apps share the same name.","commonSituations":"Electron/Chromium apps that only register in the a11y tree after accessibility is force-enabled (GNOME_ACCESSIBILITY, or Chromium's --force-renderer-accessibility); fuzzy-matching a display title; apps whose WM_CLASS differs from their AT-SPI app name.","solutions":["Use the exact AT-SPI application name — list the tree first or match WM_CLASS exactly.","Enable in-app accessibility for the target (e.g. Chromium/Electron: --force-renderer-accessibility or GTK_MODULES=gail).","Pick a unique name if several apps share one; disambiguate via a different app or window.","Confirm the app is actually running and registered: dump the AT-SPI top-level application names with pyatspi before calling."],"exampleFix":"// before\nawait backend.get_app_state({ app_ref: { name: 'chrome' } }); // ambiguous/not found\n// after\nawait backend.get_app_state({ app_ref: { name: 'Google Chrome' } }); // exact AT-SPI app name","handlingStrategy":"validation","validationCode":"const appNames = await listAtspiAppNames(); // dump tree top-level names first\nif (!appNames.includes(app_ref.name)) throw new Error(`app '${app_ref.name}' not in AT-SPI tree; known: ${appNames}`);","typeGuard":null,"tryCatchPattern":"try {\n  return await backend.get_app_state({ app_ref });\n} catch (e) {\n  if (String(e.message).includes('not found or name is ambiguous')) {\n    throw new Error(`Use exact AT-SPI app name, not '${app_ref.name}'`);\n  }\n  throw e;\n}","preventionTips":["Discover exact app names from the AT-SPI tree instead of guessing from window titles","Enable accessibility in Electron/Chromium/Java apps that hide from the a11y tree","Ensure the app is fully launched and registered before querying state"],"tags":["linux","accessibility","atspi","entity-not-found","naming"],"backgroundTag":"entity-not-found","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"}