Guides
Error Handling
Error types, ActionResult handling, and recovery patterns for both SDKs.
ActionResult
Every action returns an ActionResult indicating success or failure. Actions do not throw exceptions — always check the result.
result = session.action("e14", "click")
if result.success:
print(result.message) # "Clicked Submit"
else:
print(result.error) # "Element e14 not found"@dataclass
class ActionResult:
success: bool # True if the action succeeded
message: str # Human-readable description
error: str | None # Error details (None on success)const result = await session.action("e14", "click");
if (result.success) {
console.log(result.message); // "Clicked Submit"
} else {
console.error(result.error); // "Element e14 not found"
}interface ActionResult {
success: boolean; // true if the action succeeded
message: string; // Human-readable description
error?: string; // Error details (undefined on success)
}The most common error is using a stale element ID. Element IDs are only valid for the most recent snapshot. Always call snapshot() before interacting with elements.
Error categories
Session and tree errors
These are raised as exceptions (not returned in ActionResult):
| Error | Cause | Fix |
|---|---|---|
RuntimeError: "No tree captured. Call snapshot() first." | Called page() or find() before any snapshot() | Call snapshot() first |
ValueError: "Element 'eX' not found in current tree." | Element ID doesn't exist in the current tree | Re-capture with snapshot() and use fresh IDs |
ValueError: "Container 'eX' has no children to paginate." | Called page() on an element with no children | Check that the element is a scrollable container |
RuntimeError: "Container 'eX' appears to use virtual scrolling..." | Called page() on a virtually-scrolled container | Use action("eX", "scroll", direction="down") + snapshot() instead |
ValueError: "Invalid direction '...'" | Invalid direction passed to page() | Use one of: up, down, left, right |
Platform errors
Raised when the platform adapter can't initialize:
| Error | Platform | Fix |
|---|---|---|
RuntimeError: "Unsupported platform: ..." | Any | CUP supports win32, darwin, linux. Check sys.platform / process.platform |
RuntimeError: "Could not find csc.exe — .NET Framework 4.x is required..." | Windows | Install .NET Framework 4.x or ensure csc.exe is in PATH |
RuntimeError: "Screen Recording permission is required..." | macOS | Grant Screen Recording permission in System Settings > Privacy & Security |
RuntimeError: "libX11 not found..." | Linux | Install libx11-dev (Debian/Ubuntu) or xorg-x11-libs (Fedora) |
RuntimeError: "libXtst not found..." | Linux | Install libxtst-dev (Debian/Ubuntu) or xorg-x11-server-utils (Fedora) |
RuntimeError: "Cannot open X11 display '...'..." | Linux | Ensure DISPLAY is set and X server is running |
RuntimeError: "AT-SPI2 accessibility bus not available..." | Linux | Enable AT-SPI2: set ACCESSIBILITY_ENABLED=1 or enable in desktop settings |
RuntimeError: "gdbus not found..." | Linux (TS) | Install glib2-tools or libglib2.0-bin |
Web adapter errors
| Error | Cause | Fix |
|---|---|---|
RuntimeError: "Cannot connect to CDP at host:port..." | Chrome isn't running with remote debugging | Launch Chrome with --remote-debugging-port=9222 |
RuntimeError: "CDP endpoint at host:port has no page targets..." | Chrome is running but no tabs are open | Open at least one tab |
RuntimeError: "No browser tabs found" | CDP can't find any page targets | Verify Chrome launched with debugging flag and has tabs |
RuntimeError: "CDP error {code}: {message}" | Chrome DevTools Protocol returned an error | Check the error code and message for details |
Dependency errors
| Error | Cause | Fix |
|---|---|---|
ImportError: "Screenshot support requires the 'mss' package..." | screenshot() called without mss installed | pip install cup[screenshot] |
Action execution errors
Action failures are returned in ActionResult.error (not thrown):
| Error pattern | Cause | Fix |
|---|---|---|
"Could not resolve any key codes from combo: '...'" | Invalid key combination in press() | Check key name spelling. Use ctrl, alt, shift, enter, escape, etc. |
"SendInput failed..." | Windows input injection failed | Check if the target window accepts input. Some elevated windows block it |
"Cannot determine element position from box model" | Web element has no computable position | Element may be hidden or off-screen |
"Failed to compile Swift AX helper: ..." | macOS Swift helper compilation failed | Ensure Xcode command-line tools are installed |
Recovery patterns
Re-snapshot and retry
The most common recovery pattern — re-capture the UI and retry with fresh element IDs:
result = session.action("e14", "click")
if not result.success:
# UI may have changed — re-capture and retry
session.snapshot()
results = session.find(query="Submit")
if results:
result = session.action(results[0]["id"], "click")let result = await session.action("e14", "click");
if (!result.success) {
// UI may have changed — re-capture and retry
await session.snapshot();
const results = await session.find({ query: "Submit" });
if (results.length > 0) {
result = await session.action(results[0].id, "click");
}
}Catching platform exceptions
Wrap session creation to handle missing dependencies or unsupported platforms:
import cup
try:
session = cup.Session()
screen = session.snapshot()
except RuntimeError as e:
print(f"Platform error: {e}")
# Handle: missing dependencies, unsupported platform, etc.
except ImportError as e:
print(f"Missing dependency: {e}")
# Handle: optional dependency not installedimport { Session } from "computeruseprotocol";
try {
const session = await Session.create();
const screen = await session.snapshot();
} catch (e) {
console.error(`Platform error: ${e}`);
// Handle: missing dependencies, unsupported platform, etc.
}What's next?
- Troubleshooting — platform-specific setup issues and FAQ
- End-to-end examples — complete workflows with error handling