Skip to main content
All BAP errors follow JSON-RPC 2.0 error format with extended data providing recovery guidance for agents.

Error Response Format

{
  "code": -32012,
  "message": "Element not found",
  "data": {
    "retryable": true,
    "retryAfterMs": 500,
    "details": { "selector": { "type": "text", "value": "Submit" } },
    "recoveryHint": "Run observe() to refresh interactive elements, then retry with an updated selector"
  }
}
code
number
required
Numeric error code from the table below.
message
string
required
Human-readable error message.
data.retryable
boolean
Whether the operation can be retried.
data.retryAfterMs
number
Suggested delay before retrying (milliseconds).
data.details
object
Additional context (selector used, page ID, etc.).
data.recoveryHint
string
Actionable suggestion for the agent on how to recover from the error.

Error Code Reference

JSON-RPC Standard Errors

CodeNameRetryableRecovery Hint
-32700ParseErrorNoFix the JSON syntax in the request
-32600InvalidRequestNoEnsure the request follows JSON-RPC 2.0 structure
-32601MethodNotFoundNoCheck the method name against the protocol spec
-32602InvalidParamsNoValidate parameters against the method schema
-32603InternalErrorNoReport as a bug — this is an unexpected server error

Server State Errors

CodeNameRetryableRecovery Hint
-32000ServerErrorYesGeneric server error — retry after a delay
-32001NotInitializedNoSend an initialize request before calling any other method
-32002AlreadyInitializedNoThe connection is already initialized; proceed with commands

Browser Errors

CodeNameRetryableRecovery Hint
-32010BrowserNotLaunchedNoCall browser/launch to start a browser
-32011PageNotFoundNoCall page/list to see available pages, or page/create to open a new one
-32023ContextNotFoundNoThe browser context does not exist
-32024ResourceLimitExceededNoMax pages or contexts reached — close some before creating new ones

Element Errors

CodeNameRetryableRecovery Hint
-32012ElementNotFoundYesRun observe() to refresh interactive elements, then retry with an updated selector
-32013ElementNotVisibleYesScroll the element into view or wait for it to appear, then retry
-32014ElementNotEnabledYesWait for the element to become enabled (e.g., form validation), then retry
-32020SelectorAmbiguousNoUse a more specific selector (testId, CSS with nth-child, or role with exact name)
CodeNameRetryableRecovery Hint
-32015NavigationFailedYesCheck the URL is valid and accessible, then retry
-32016TimeoutYesIncrease timeout or wait for the page to finish loading
-32017TargetClosedNoThe page or context was closed — create a new one
-32021ActionFailedVariesRun observe() to verify element state, then retry

Security and Approval Errors

CodeNameRetryableRecovery Hint
-32030ApprovalDeniedNoThe human operator denied this action
-32040FrameNotFoundNoThe target frame does not exist on this page
-32041DomainNotAllowedNoThe domain is not in the server’s allowlist

Error Handling Patterns

Retry with Backoff

For retryable errors, use the retryAfterMs hint:
try {
  await client.click(text("Submit"));
} catch (error) {
  if (error instanceof BAPError && error.retryable) {
    await sleep(error.retryAfterMs ?? 1000);
    // Re-observe then retry
    const obs = await client.observe();
    await client.click(obs.interactiveElements[0].selector);
  }
}

Observe-Retry Pattern

The most common recovery pattern for element errors is to re-observe and retry:
try {
  await client.click(ref("@e5"));
} catch (error) {
  if (error.code === -32012) {
    // ElementNotFound
    const obs = await client.observe();
    // Find the element again using a different selector
    const target = obs.interactiveElements.find((el) => el.name === "Submit");
    if (target) await client.click(target.selector);
  }
}

Structured Error Classes

Both SDKs provide typed error classes for precise error handling:
import { BAPError, BAPElementNotFoundError, BAPTimeoutError } from "@browseragentprotocol/client";

try {
  await client.click(role("button", "Submit"));
} catch (error) {
  if (error instanceof BAPElementNotFoundError) {
    console.log("Recovery:", error.recoveryHint);
  } else if (error instanceof BAPTimeoutError) {
    console.log("Timed out after:", error.details?.timeout, "ms");
  }
}