> ## Documentation Index
> Fetch the complete documentation index at: https://docs.webrun.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Error Codes Reference

> Complete reference of all WebRun API error codes, status codes, and solutions

## Quick Fixes Summary

Jump to the solution for common errors:

| Error Code                                        | Quick Fix                                           | Details                        |
| ------------------------------------------------- | --------------------------------------------------- | ------------------------------ |
| [INVALID\_API\_KEY](#invalid_api_key)             | Verify API key in Settings → API Keys               | [Link](#invalid_api_key)       |
| [SESSION\_NOT\_FOUND](#session_not_found)         | Create new session with POST /start/start-session   | [Link](#session_not_found)     |
| [SESSION\_EXPIRED](#session_expired)              | Sessions expire after maxDuration - create new one  | [Link](#session_expired)       |
| [SESSION\_LIMIT\_REACHED](#session_limit_reached) | Terminate unused sessions or upgrade plan           | [Link](#session_limit_reached) |
| [TASK\_TIMEOUT](#task_timeout)                    | Increase maxDuration or simplify task               | [Link](#task_timeout)          |
| [TASK\_ALREADY\_RUNNING](#task_already_running)   | Wait for completion or stop with newState: "stop"   | [Link](#task_already_running)  |
| [RATE\_LIMIT\_EXCEEDED](#rate_limit_exceeded)     | Wait before retrying, implement exponential backoff | [Link](#rate_limit_exceeded)   |
| [INSUFFICIENT\_BALANCE](#insufficient_balance)    | Add credits at webrun.ai/billing                    | [Link](#insufficient_balance)  |
| [NAVIGATION\_TIMEOUT](#navigation_timeout)        | Retry request or check if website is accessible     | [Link](#navigation_timeout)    |
| [ELEMENT\_NOT\_FOUND](#element_not_found)         | Rephrase task or wait for page load                 | [Link](#element_not_found)     |

***

## Error Response Format

All errors follow a consistent structure:

```json theme={null}
{
  "success": false,
  "error": "Human-readable error message",
  "code": "ERROR_CODE",
  "details": { /* Additional context */ }
}
```

***

## HTTP Status Codes

| Status | Meaning               | Common Causes                      |
| ------ | --------------------- | ---------------------------------- |
| `200`  | Success               | Request completed successfully     |
| `400`  | Bad Request           | Invalid parameters, malformed JSON |
| `401`  | Unauthorized          | Missing or invalid API key         |
| `402`  | Payment Required      | Insufficient account balance       |
| `404`  | Not Found             | Session or task does not exist     |
| `429`  | Too Many Requests     | Rate limit exceeded                |
| `500`  | Internal Server Error | Server-side issue                  |
| `503`  | Service Unavailable   | System maintenance or overload     |

***

## Authentication Errors

### INVALID\_API\_KEY

```json theme={null}
{
  "success": false,
  "error": "Invalid API key",
  "code": "INVALID_API_KEY"
}
```

**Solution:** Verify your API key is correct and active in Settings → API Keys.

**Related:**

* [Authentication Guide](/getting-started/authentication)
* [API Keys Management](/essentials/settings)

***

### API\_KEY\_EXPIRED

```json theme={null}
{
  "success": false,
  "error": "API key has expired",
  "code": "API_KEY_EXPIRED"
}
```

**Solution:** Generate a new API key in your account settings.

**Related:**

* [Regenerating API Keys](/essentials/settings)

***

### UNAUTHORIZED

```json theme={null}
{
  "success": false,
  "error": "Authorization header missing",
  "code": "UNAUTHORIZED"
}
```

**Solution:** Include `Authorization: Bearer YOUR_API_KEY` header in all requests.

**Example:**

```javascript theme={null}
const response = await fetch("https://connect.webrun.ai/start/start-session", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${YOUR_API_KEY}`
  },
  body: JSON.stringify({ prompt: "Navigate to example.com" })
});
```

**Related:**

* [Authentication Guide](/getting-started/authentication)

***

## Session Errors

### SESSION\_NOT\_FOUND

```json theme={null}
{
  "success": false,
  "error": "Session a1b2c3d4e5f6 does not exist or has expired",
  "code": "SESSION_NOT_FOUND"
}
```

**Causes:**

* Session was terminated
* Session expired (5 min of inactivity)
* Invalid sessionId

**Solution:** Create a new session with `POST /start/start-session`.

**Related:**

* [Session Lifecycle](/concepts/sessions)
* [Start Session API](/api-reference/sessions/start-session)

***

### SESSION\_EXPIRED

```json theme={null}
{
  "success": false,
  "error": "Session expired after 300 seconds of inactivity",
  "code": "SESSION_EXPIRED"
}
```

**Solution:** Sessions expire after `maxDuration`. Create a new session for continuation.

**Best Practice:**

```javascript theme={null}
// Set appropriate maxDuration
const session = await fetch("https://connect.webrun.ai/start/start-session", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${apiKey}`
  },
  body: JSON.stringify({
    prompt: "Your task",
    maxDuration: 300000 // max task duration in milliseconds
  })
});
```

**Related:**

* [Session Timeouts](/concepts/sessions#timeouts)

***

### SESSION\_LIMIT\_REACHED

```json theme={null}
{
  "success": false,
  "error": "Maximum concurrent sessions reached (limit: 5)",
  "code": "SESSION_LIMIT_REACHED",
  "details": {
    "current": 5,
    "limit": 5
  }
}
```

**Solution:** Terminate unused sessions or upgrade your plan.

**Clean up sessions:**

```javascript theme={null}
// Terminate session when done
await fetch("https://connect.webrun.ai/start/send-message", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${apiKey}`
  },
  body: JSON.stringify({
    sessionId,
    message: { actionType: "state", newState: "terminate" }
  })
});
```

**Related:**

* [Plan Limits](/pricing)
* [Session Management](/concepts/sessions)

***

### INSTANCE\_UNAVAILABLE

```json theme={null}
{
  "success": false,
  "error": "No browser instances available",
  "code": "INSTANCE_UNAVAILABLE"
}
```

**Solution:** Wait and retry, or contact support if persistent.

**Retry with backoff:**

```javascript theme={null}
async function createSessionWithRetry(prompt, apiKey, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch("https://connect.webrun.ai/start/start-session", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "Authorization": `Bearer ${apiKey}`
        },
        body: JSON.stringify({ prompt })
      });

      const data = await response.json();
      if (response.ok) return data;

      if (data.code === "INSTANCE_UNAVAILABLE" && i < maxRetries - 1) {
        await new Promise(r => setTimeout(r, 2000 * Math.pow(2, i)));
        continue;
      }

      throw new Error(data.error);
    } catch (error) {
      if (i === maxRetries - 1) throw error;
    }
  }
}
```

***

## Task Execution Errors

### TASK\_NOT\_FOUND

```json theme={null}
{
  "success": false,
  "error": "Task x9y8z7w6v5u4 not found in session a1b2c3d4e5f6",
  "code": "TASK_NOT_FOUND"
}
```

**Solution:** Verify taskId and sessionId are correct.

**Related:**

* [Task Polling](/api-reference/tasks/poll-task)

***

### TASK\_ALREADY\_RUNNING

```json theme={null}
{
  "success": false,
  "error": "A task is already running in this session",
  "code": "TASK_ALREADY_RUNNING"
}
```

**Solution:** Wait for current task to complete or stop it with `newState: "stop"`.

**Stop running task:**

```javascript theme={null}
await fetch("https://connect.webrun.ai/start/send-message", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${apiKey}`
  },
  body: JSON.stringify({
    sessionId,
    message: { actionType: "state", newState: "stop" }
  })
});
```

**Related:**

* [Task States](/concepts/tasks#states)

***

### TASK\_TIMEOUT

```json theme={null}
{
  "success": false,
  "error": "Task exceeded maximum duration of 60000ms",
  "code": "TASK_TIMEOUT",
  "usage": {
    "inputTokens": 25000,
    "outputTokens": 8000,
    "cost": 0.0245
  }
}
```

**Solution:** Increase `maxDuration` or simplify the task.

**Adjust timeouts:**

```javascript theme={null}
const response = await fetch("https://connect.webrun.ai/start/run-task", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${apiKey}`
  },
  body: JSON.stringify({
    sessionId,
    prompt: "Complex task",
    maxDuration: 120000 // 2 minutes
  })
});
```

**Related:**

* [Task Configuration](/concepts/tasks#configuration)
* [Managing Costs](/troubleshooting/common-issues#high-costs)

***

### INVALID\_TASK\_DETAILS

```json theme={null}
{
  "success": false,
  "error": "prompt cannot be empty",
  "code": "INVALID_TASK_DETAILS"
}
```

**Solution:** Provide a valid task description.

**Good task examples:**

```javascript theme={null}
// Good - specific and actionable
prompt: "Navigate to example.com and click the 'Sign Up' button"

// Good - clear objective
prompt: "Search for 'laptop' on amazon.com and get the price of the first result"

// Bad - too vague
prompt: "do something"
```

**Related:**

* [Writing Effective Tasks](/usage-guides/best-practices)

***

## Browser & Navigation Errors

### NAVIGATION\_TIMEOUT

```json theme={null}
{
  "success": false,
  "error": "Navigation timeout after 30 seconds",
  "code": "NAVIGATION_TIMEOUT",
  "details": {
    "url": "https://example.com",
    "timeout": 30000
  }
}
```

**Causes:**

* Slow website
* Network issues
* Website blocking automated access

**Solution:**

* Retry the request
* Check if website is accessible
* Use `startingUrl` if navigating to a specific page

**Example:**

```javascript theme={null}
const session = await fetch("https://connect.webrun.ai/start/start-session", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${apiKey}`
  },
  body: JSON.stringify({
    prompt: "Click the login button",
    startingUrl: "https://example.com/login" // Start directly at destination
  })
});
```

**Related:**

* [Navigation Options](/api-reference/sessions/start-session#parameters)

***

### PAGE\_CRASH

```json theme={null}
{
  "success": false,
  "error": "Browser page crashed during execution",
  "code": "PAGE_CRASH"
}
```

**Solution:** Retry the task. If persistent, report to support with session details.

**Related:**

* [Getting Help](/troubleshooting/errors-reference#getting-help)

***

### ELEMENT\_NOT\_FOUND

```json theme={null}
{
  "success": false,
  "error": "Could not locate element matching criteria",
  "code": "ELEMENT_NOT_FOUND"
}
```

**Causes:**

* Page structure changed
* Element inside iframe
* Element not yet loaded

**Solution:** Rephrase task description or wait for page load.

**Tips:**

```javascript theme={null}
// Instead of: "Click the button"
// Try: "Click the blue 'Submit' button at the bottom of the form"

// For dynamic content:
prompt: "Wait for the results to load, then click the first product"
```

**Related:**

* [Task Best Practices](/usage-guides/best-practices)

***

## Rate Limiting & Network Errors

### RATE\_LIMIT\_EXCEEDED

```json theme={null}
{
  "success": false,
  "message": "Rate limit exceeded. Please try again later."
}
```

**Solution:** Wait before retrying. Implement exponential backoff.

**Rate Limits by Endpoint:**

* `POST /start/start-session`: 10 requests/minute per user
* `POST /start/send-message`: 10 requests/minute per user
* `POST /start/run-task`: 10 requests/minute per user
* `GET /task/:sessionId/:taskId`: No rate limit

**Note:** Rate limits are per user (API key owner), not per API key.

**Exponential Backoff Implementation:**

```javascript theme={null}
async function makeRequestWithRetry(url, options, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      const response = await fetch(url, options);
      const data = await response.json();

      if (response.ok) return data;

      // Don't retry client errors (4xx) except rate limits
      if (response.status >= 400 && response.status < 500 && response.status !== 429) {
        throw new Error(`${data.code}: ${data.error}`);
      }

      // Retry on 5xx errors and rate limits
      if (attempt < maxRetries - 1) {
        const delay = Math.min(1000 * Math.pow(2, attempt), 10000);
        console.log(`Retry ${attempt + 1}/${maxRetries} after ${delay}ms`);
        await new Promise(r => setTimeout(r, delay));
        continue;
      }

      throw new Error(`${data.code}: ${data.error}`);

    } catch (error) {
      if (attempt === maxRetries - 1) throw error;
    }
  }
}
```

**Related:**

* [API Limits](/api-reference/introduction#rate-limits)

***

## Billing & Payment Errors

### INSUFFICIENT\_BALANCE

```json theme={null}
{
  "success": false,
  "error": "Insufficient account balance ($0.50 remaining, $2.00 required)",
  "code": "INSUFFICIENT_BALANCE",
  "details": {
    "balance": 0.50,
    "required": 2.00
  }
}
```

**Solution:** Add credits to your account at [webrun.ai/billing](https://webrun.ai/billing).

**Monitor balance:**

* Check your balance regularly in the dashboard
* Set up low balance alerts
* Consider auto-recharge options

**Related:**

* [Billing & Pricing](/pricing)
* [Usage Tracking](/essentials/dashboard)

***

### PAYMENT\_FAILED

```json theme={null}
{
  "success": false,
  "error": "Payment method declined",
  "code": "PAYMENT_FAILED"
}
```

**Solution:** Update payment method in Settings → Billing.

**Common causes:**

* Expired card
* Insufficient funds
* Card issuer declined
* Invalid billing address

***

## Validation Errors

### INVALID\_PARAMETER

```json theme={null}
{
  "success": false,
  "error": "Invalid parameter 'maxDuration': must be at least 1000",
  "code": "INVALID_PARAMETER",
  "details": {
    "parameter": "maxDuration",
    "value": 500000,
    "min": 1000
  }
}
```

**Solution:** Check parameter requirements in API documentation.

**Parameter Ranges:**

* `maxDuration`: 1,000 - 300,000 ms (max task duration, default 5 minutes)
* `maxInputTokens`: 1,000 - 100,000 tokens
* `maxOutputTokens`: 100 - 50,000 tokens

**Related:**

* [API Reference](/api-reference/introduction)

***

### MISSING\_REQUIRED\_FIELD

```json theme={null}
{
  "success": false,
  "error": "Missing required field: task.prompt",
  "code": "MISSING_REQUIRED_FIELD",
  "details": {
    "field": "task.prompt"
  }
}
```

**Solution:** Include all required fields in request body.

**Required fields by endpoint:**

**POST /start/start-session:**

* `prompt` (string)

**POST /start/send-message:**

* `sessionId` (string)
* `message` (object)

**POST /start/run-task:**

* `sessionId` (string)
* `prompt` (string)

**Related:**

* [API Reference](/api-reference/introduction)

***

## MCP-Specific Errors

### MCP\_SESSION\_NOT\_FOUND

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32603,
    "message": "Session not found"
  }
}
```

**Solution:** Check your MCP session ID or reconnect to the SSE endpoint.

**Related:**

* [MCP Integration](/integrations/mcp)

***

### MCP\_METHOD\_NOT\_FOUND

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32601,
    "message": "Method not found: invalid_method"
  }
}
```

**Solution:** Use valid MCP methods (tools/list, tools/call, etc.).

**Valid MCP methods:**

* `tools/list`
* `tools/call`
* `resources/list`
* `resources/read`

**Related:**

* [MCP Methods](/integrations/mcp#methods)

***

### MCP\_INVALID\_REQUEST

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32600,
    "message": "Invalid request"
  }
}
```

**Solution:** Ensure request follows JSON-RPC 2.0 format with `jsonrpc: "2.0"`.

**Example:**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list",
  "params": {}
}
```

**Related:**

* [MCP Protocol](/integrations/mcp#protocol)

***

## Error Handling Best Practices

### Complete Error Handling Example

```javascript theme={null}
async function executeTaskWithRetry(prompt, apiKey) {
  let sessionId = null;

  try {
    // Create session with retry
    const session = await makeRequestWithRetry(
      "https://connect.webrun.ai/start/start-session",
      {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "Authorization": `Bearer ${apiKey}`
        },
        body: JSON.stringify({ prompt })
      }
    );

    sessionId = session.sessionId;

    // Execute task with guardrail handling
    const result = await executeTaskWithGuardrails(
      sessionId,
      prompt,
      apiKey
    );

    return result;

  } catch (error) {
    console.error("Task execution failed:", error.message);

    // Clean up session on error
    if (sessionId) {
      await terminateSession(sessionId, apiKey);
    }

    throw error;
  }
}

async function terminateSession(sessionId, apiKey) {
  try {
    await fetch("https://connect.webrun.ai/start/send-message", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${apiKey}`
      },
      body: JSON.stringify({
        sessionId,
        message: { actionType: "state", newState: "terminate" }
      })
    });
  } catch (error) {
    console.error("Failed to terminate session:", error.message);
  }
}
```

### Handling Guardrails

```javascript theme={null}
async function executeTaskWithGuardrails(sessionId, prompt, apiKey) {
  let attempts = 0;
  const maxGuardrailAttempts = 3;

  while (attempts < maxGuardrailAttempts) {
    const result = await pollForResult(sessionId, taskId, apiKey);

    if (result.type === "task_completed") {
      return result;
    }

    if (result.type === "guardrail_trigger") {
      console.log(`Guardrail triggered: ${result.data.value}`);

      // Get user input
      const userInput = await promptUser(result.data.value);

      // Resume with input
      await fetch("https://connect.webrun.ai/start/send-message", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "Authorization": `Bearer ${apiKey}`
        },
        body: JSON.stringify({
          sessionId,
          message: {
            actionType: "guardrail",
            prompt: userInput,
            newState: "resume"
          }
        })
      });

      attempts++;
      continue;
    }

    throw new Error("Unexpected result type");
  }

  throw new Error("Maximum guardrail attempts exceeded");
}
```

**Related:**

* [Guardrails Guide](/usage-guides/guardrails)
* [Error Handling Examples](/usage-guides/error-handling)

***

## Debugging Checklist

When encountering issues:

* [ ] Verify API key is valid and has correct permissions
* [ ] Check account balance is sufficient
* [ ] Confirm session/task IDs are correct
* [ ] Review task instructions for clarity
* [ ] Check network connectivity
* [ ] Look for error codes in responses
* [ ] Enable verbose logging
* [ ] Test with simpler task first
* [ ] Check system status page
* [ ] Review usage limits for your plan

***

## Getting Help

If you're still experiencing issues:

1. **Documentation:** Review relevant API docs
2. **Status Page:** Check [status.webrun.ai](https://status.webrun.ai)
3. **Support:** Email [support@webrun.ai](mailto:support@webrun.ai) with:
   * Error code and full error response
   * Session ID and task ID
   * Task description
   * Timestamp of occurrence
   * Steps to reproduce

***

## Related Resources

<CardGroup cols={2}>
  <Card title="Common Issues" icon="circle-exclamation" href="/troubleshooting/common-issues">
    Solutions for frequent problems
  </Card>

  <Card title="FAQs" icon="messages-question" href="/troubleshooting/faqs">
    Answers to common questions
  </Card>

  <Card title="Best Practices" icon="star" href="/usage-guides/best-practices">
    Guidelines for optimal usage
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/introduction">
    Complete endpoint documentation
  </Card>
</CardGroup>
