testdriver:errors

SkillDev tools

Custom error classes and error handling

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the testdriver:errors skill

What this skill tells your AI

The instructions your AI receives, as published by testdriverai/testdriverai in ai/skills/testdriver-errors/SKILL.md and read by ahel’s review.

Overview

TestDriver provides custom error classes with rich debugging information. These are exported from the SDK and can be used for instanceof checks in your tests.

import TestDriver, { ElementNotFoundError, AIError } from 'testdriverai';

ElementNotFoundError

Thrown when find() cannot locate an element on screen, or when calling click()/hover() on an unfound element.

try {
  await testdriver.find('nonexistent button').click();
} catch (error) {
  if (error instanceof ElementNotFoundError) {
    console.log(error.description);       // "nonexistent button"
    console.log(error.screenshotPath);    // path to debug screenshot
    console.log(error.pixelDiffPath);     // path to pixel diff image
  }
}

Properties

Enhanced Message

The error message is automatically enhanced with debugging information:

Element not found: "submit button"

=== Element Debug Info ===
Element: submit button
Cache Hit: false
Similarity: 0.23
Cache Strategy: pixel-diff
Threshold: 0.05
AI Response Element: null

Stack Trace Cleaning

Stack traces are automatically cleaned to remove internal SDK frames (Element.*, sdk.js internals), showing only your test code for easier debugging.

AIError

Thrown when act() exhausts all retry attempts.

try {
  await testdriver.act('perform complex workflow', { tries: 3 });
} catch (error) {
  if (error instanceof AIError) {
    console.log(error.task);       // "perform complex workflow"
    console.log(error.tries);     // 3
    console.log(error.duration);  // 15234 (ms)
    console.log(error.cause);     // underlying Error
  }
}

Properties

Enhanced Message

AI failed: Element not found after 3 attempts

=== AI Execution Details ===
Task: perform complex workflow
Tries: 3 / 3
Duration: 15234ms
Cause: ElementNotFoundError: Element not found: "submit button"

Internal Error Classes

These errors are used internally by the agent and are not exported, but may appear as the cause of an AIError:

MatchError

Thrown when element matching fails (text, image, or assertion).

PropertyTypeDescription
fatalbooleanIf true, cannot be healed. Default: false
attachScreenshotbooleanAlways true — a screenshot is attached to the error

CommandError

Thrown for invalid arguments or unsupported operations.

PropertyTypeDescription
fatalbooleanAlways true
attachScreenshotbooleanAlways false

Soft Assert Mode

Inside act(), assertions run in soft assert mode. When an assertion fails, it returns the failure result instead of throwing, allowing the AI to process the failure and adjust its approach.

// Inside act(), assertion failures don't throw
await testdriver.act('verify the dashboard shows correct data', {
  tries: 3,
});
// The AI can see assertion results and self-correct

This is automatic — you don't need to configure it. Regular assert() calls outside of act() will throw normally on failure.

Error Handling Patterns

Catching Specific Errors

import TestDriver, { ElementNotFoundError, AIError } from 'testdriverai';

try {
  await testdriver.find('submit button').click();
} catch (error) {
  if (error instanceof ElementNotFoundError) {
    // Element wasn't found — check screenshot for debugging
    console.log('Debug screenshot:', error.screenshotPath);
  } else if (error instanceof AIError) {
    // AI exhausted retries
    console.log(`Failed after ${error.tries} tries in ${error.duration}ms`);
  } else {
    throw error; // Unexpected error
  }
}

Using Debug Screenshots

try {
  const el = await testdriver.find('checkout button');
  await el.click();
} catch (error) {
  if (error instanceof ElementNotFoundError) {
    // Screenshot of what the screen looked like
    console.log('Screen:', error.screenshotPath);
    // Pixel diff showing cache comparison
    console.log('Diff:', error.pixelDiffPath);
    // Full AI response metadata
    console.log('AI:', JSON.stringify(error.aiResponse, null, 2));
  }
}

Types

class ElementNotFoundError extends Error {
  name: 'ElementNotFoundError';
  description: string;
  screenshotPath: string | null;
  pixelDiffPath: string | null;
  cachedImagePath: string | null;
  aiResponse: Record<string, any> | null;
  timestamp: string;
}

class AIError extends Error {
  name: 'AIError';
  task: string;
  tries: number;
  maxTries: number;
  duration: number;
  cause?: Error;
  timestamp: string;
}

Signals

GitHub stars
242
Forks
35
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
testdriver-errors
Source
github.com/testdriverai/testdriverai