{"record":{"id":"c31bf9948249e083","repo":"n8n-io/n8n","slug":"no-monitors-available","errorCode":null,"errorMessage":"No monitors available","messagePattern":"No monitors available","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/computer-use/src/tools/monitor-utils.ts","lineNumber":6,"sourceCode":"import type { Monitor } from 'node-screenshots';\n\nexport async function getPrimaryMonitor(): Promise<Monitor> {\n\tconst { Monitor: MonitorClass } = await import('node-screenshots');\n\tconst monitors = MonitorClass.all();\n\tif (monitors.length === 0) throw new Error('No monitors available');\n\treturn monitors.find((m) => m.isPrimary()) ?? monitors[0];\n}\n","sourceCodeStart":1,"sourceCodeEnd":9,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/computer-use/src/tools/monitor-utils.ts#L1-L9","documentation":"Thrown by getPrimaryMonitor() in @n8n/computer-use when node-screenshots' MonitorClass.all() returns an empty array, meaning the host exposes no display devices. The function is used to pick a primary monitor for screen-capture tooling. The error is a bare `new Error(...)` (no n8n error class), so callers must match on message text.","triggerScenarios":"Calling getPrimaryMonitor() on a headless server, a container without a virtual framebuffer (no Xvfb), a CI runner with no attached display, or an SSH session without X forwarding. Also triggered on OSes where node-screenshots cannot enumerate screens (missing native deps).","commonSituations":"Running the computer-use tool inside Docker/k8s without a display server; CI environments; remote SSH-only boxes; a misconfigured Xvfb; a Linux box where libx11/libxcb native libraries are absent so node-screenshots returns [].","solutions":["Run the host with an attached display or start a virtual framebuffer: `xvfb-run -s '-screen 0 1920x1080x24' <cmd>`.","If running in Docker, add a virtual display (`apt-get install xvfb` then launch Xvfb) or use an image that ships one.","Confirm node-screenshots can enumerate monitors in isolation before invoking the tool: `import('node-screenshots').then(m => console.log(m.Monitor.all().length))`.","Guard the call site: if getPrimaryMonitor() is optional, wrap it in try/catch and degrade gracefully or surface a user-facing 'no display' message.","On Linux, ensure libx11, libxcb, libxrandr and a running X server (or Wayland compositor) are present."],"exampleFix":"// before\nconst monitor = await getPrimaryMonitor();\n\n// after\nlet monitor;\ntry {\n  monitor = await getPrimaryMonitor();\n} catch (err) {\n  if (err instanceof Error && err.message === 'No monitors available') {\n    throw new OperationalError('Screen capture is unavailable: no display detected. Run with an attached or virtual (Xvfb) display.');\n  }\n  throw err;\n}","handlingStrategy":"validation","validationCode":"import('node-screenshots').then(({ Monitor }) => {\n  const count = Monitor.all().length;\n  if (count === 0) {\n    // surface 'no display' to the user; do not call getPrimaryMonitor()\n  }\n});","typeGuard":"function hasDisplay(monitors: unknown[]): monitors is { isPrimary(): boolean }[] {\n  return Array.isArray(monitors) && monitors.length > 0;\n}","tryCatchPattern":"try {\n  const monitor = await getPrimaryMonitor();\n} catch (err) {\n  if (err instanceof Error && err.message === 'No monitors available') {\n    // degrade or instruct user to attach/Xvfb a display\n  } else throw err;\n}","preventionTips":["In headless environments, start Xvfb before invoking screen-capture tools.","Pre-flight check display availability via node-screenshots before exposing the tool to users.","Document that the computer-use tool requires a display; gate feature flags on its presence."],"tags":["runtime","hardware","display","computer-use","headless"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}