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

# Error Handling

> Handle SDK errors gracefully

<Note>**Early Beta** -- The Web SDK is in early beta. APIs may change between releases.</Note>

## Overview

The RunAnywhere Web SDK provides structured error handling through `SDKError` with specific error codes. This guide covers error types, handling patterns, and recovery strategies.

## SDKError Structure

```typescript theme={null}
import { SDKError, SDKErrorCode } from '@runanywhere/web'

class SDKError extends Error {
  readonly code: SDKErrorCode
  readonly details?: string
  readonly message: string
}
```

## Checking for SDK Errors

```typescript theme={null}
import { SDKError, SDKErrorCode } from '@runanywhere/web'
import { TextGeneration } from '@runanywhere/web-llamacpp'

try {
  const { stream, result } = await TextGeneration.generateStream('Hello', { maxTokens: 100 })
  for await (const token of stream) {
    /* ... */
  }
} catch (err) {
  if (err instanceof SDKError) {
    console.log('Code:', err.code)
    console.log('Message:', err.message)
    console.log('Details:', err.details)
  } else {
    console.error('Unexpected error:', err)
  }
}
```

## Error Codes

### Initialization Errors

| Code                   | Value | Description             | Recovery                           |
| ---------------------- | ----- | ----------------------- | ---------------------------------- |
| `NotInitialized`       | -100  | SDK not initialized     | Call `RunAnywhere.initialize()`    |
| `AlreadyInitialized`   | -101  | SDK already initialized | Use existing instance or `reset()` |
| `InvalidConfiguration` | -102  | Invalid config options  | Check initialization options       |
| `InitializationFailed` | -103  | Init failed             | Check browser compatibility        |

### Model Errors

| Code                 | Value | Description           | Recovery                              |
| -------------------- | ----- | --------------------- | ------------------------------------- |
| `ModelNotFound`      | -110  | Model not in registry | Register model first                  |
| `ModelLoadFailed`    | -111  | Failed to load model  | Check model path, format              |
| `ModelInvalidFormat` | -112  | Unsupported format    | Use GGUF or ONNX                      |
| `ModelNotLoaded`     | -113  | No model loaded       | Call `ModelManager.loadModel()` first |

### Generation Errors

| Code                  | Value | Description            | Recovery                      |
| --------------------- | ----- | ---------------------- | ----------------------------- |
| `GenerationFailed`    | -130  | Text generation failed | Check model, reduce tokens    |
| `GenerationCancelled` | -131  | Generation cancelled   | Expected if `cancel()` called |
| `GenerationTimeout`   | -132  | Generation timed out   | Reduce maxTokens              |

### Download Errors

| Code             | Value | Description     | Recovery                    |
| ---------------- | ----- | --------------- | --------------------------- |
| `DownloadFailed` | -160  | Download failed | Check network, CORS headers |

### Storage Errors

| Code           | Value | Description              | Recovery                |
| -------------- | ----- | ------------------------ | ----------------------- |
| `StorageError` | -180  | Storage operation failed | Check OPFS availability |

### WASM Errors

| Code             | Value | Description                | Recovery                              |
| ---------------- | ----- | -------------------------- | ------------------------------------- |
| `WASMLoadFailed` | -900  | WASM module failed to load | Check WASM file paths, bundler config |
| `WASMNotLoaded`  | -901  | WASM module not loaded     | Register backends first               |

## Static Factory Methods

`SDKError` provides convenient factory methods:

```typescript theme={null}
SDKError.notInitialized()
SDKError.wasmNotLoaded()
SDKError.modelNotFound('my-model')
SDKError.generationFailed('Context window exceeded')
SDKError.fromRACResult(resultCode, 'details')
```

## Handling Patterns

### Basic Error Handling

```typescript theme={null}
import { SDKError, SDKErrorCode } from '@runanywhere/web'
import { TextGeneration } from '@runanywhere/web-llamacpp'

try {
  const { stream } = await TextGeneration.generateStream(prompt, { maxTokens: 200 })
  for await (const token of stream) {
    /* update UI */
  }
} catch (err) {
  if (err instanceof SDKError) {
    switch (err.code) {
      case SDKErrorCode.NotInitialized:
        console.error('SDK not initialized — call RunAnywhere.initialize() first')
        break
      case SDKErrorCode.ModelNotLoaded:
        console.error('No model loaded — call ModelManager.loadModel() first')
        break
      case SDKErrorCode.GenerationFailed:
        console.error('Generation failed:', err.details)
        break
      case SDKErrorCode.GenerationCancelled:
        break
      default:
        console.error(`SDK error [${err.code}]: ${err.message}`)
    }
  }
}
```

### WASM Memory Crash Handling

VLM inference can occasionally trigger WASM memory errors. These are recoverable:

```typescript theme={null}
import { VLMWorkerBridge } from '@runanywhere/web-llamacpp'

try {
  const result = await VLMWorkerBridge.shared.process(rgbPixels, width, height, prompt, options)
} catch (err) {
  const msg = (err as Error).message
  if (msg.includes('memory access out of bounds') || msg.includes('RuntimeError')) {
    // Recoverable — skip this frame and retry
    console.warn('WASM crash, will retry next frame')
  } else {
    throw err
  }
}
```

### WASM Binary Served as HTML (Production)

In production, if your server has a SPA catch-all route that serves `index.html` for unknown paths, `.wasm` file requests will return HTML instead of the binary. The WASM compiler receives HTML bytes and throws:

```
CompileError: WebAssembly.instantiate(): expected magic word 00 61 73 6d, found 3c 21 44 4f
```

The bytes `3c 21 44 4f` decode to `<!DO` — the start of an HTML document. **Fix:** ensure static asset serving (with correct MIME types) comes before SPA catch-all routing. See [Installation troubleshooting](/web/installation#wasm-loads-html-instead-of-binary-production).

### Camera "source width is 0"

Calling `VideoCapture.captureFrame()` before the video stream is fully initialized causes:

```
Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The source width is 0.
```

**Fix:** Wait for the video element's `loadedmetadata` event or check `videoElement.videoWidth > 0` before capturing. See [VLM camera readiness](/web/vlm#waiting-for-camera-readiness).

### VLM Worker "non-JavaScript MIME type"

```
Failed to load module script: The server responded with a non-JavaScript MIME type of "text/html"
```

The VLM Web Worker URL is resolving to your SPA's `index.html`. **Fix:**

1. Use `COEP: credentialless` (not `require-corp`)
2. Ensure `.js` files are served as static assets before the catch-all route
3. Add `worker: { format: 'es' }` to your Vite config

### Retry Logic

```typescript theme={null}
async function withRetry<T>(operation: () => Promise<T>, maxRetries = 2): Promise<T> {
  let lastError: Error | null = null

  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    try {
      return await operation()
    } catch (err) {
      lastError = err as Error

      if (!(err instanceof SDKError)) throw err

      if (
        [
          SDKErrorCode.NotInitialized,
          SDKErrorCode.ModelNotFound,
          SDKErrorCode.ModelInvalidFormat,
          SDKErrorCode.GenerationCancelled,
        ].includes(err.code)
      ) {
        throw err
      }

      if (attempt < maxRetries) {
        await new Promise((r) => setTimeout(r, 1000 * (attempt + 1)))
        continue
      }
    }
  }

  throw lastError
}
```

### User-Friendly Messages

```typescript theme={null}
function getUserMessage(err: SDKError): string {
  switch (err.code) {
    case SDKErrorCode.NotInitialized:
      return 'The AI system is still loading. Please wait.'
    case SDKErrorCode.ModelNotLoaded:
      return 'No AI model is loaded. Please download a model first.'
    case SDKErrorCode.GenerationFailed:
      return 'Failed to generate a response. Please try again.'
    case SDKErrorCode.GenerationCancelled:
      return 'Response generation was cancelled.'
    case SDKErrorCode.WASMLoadFailed:
      return 'Failed to load the AI engine. Please refresh the page.'
    case SDKErrorCode.DownloadFailed:
      return 'Model download failed. Check your internet connection.'
    case SDKErrorCode.StorageError:
      return 'Storage error. Try clearing browser data and reloading.'
    default:
      return err.message || 'An unexpected error occurred.'
  }
}
```

### React Error Hook

```typescript useSDKError.ts theme={null}
import { useState, useCallback } from 'react'
import { SDKError, SDKErrorCode } from '@runanywhere/web'

export function useSDKError() {
  const [error, setError] = useState<SDKError | null>(null)

  const handleError = useCallback((err: unknown) => {
    if (err instanceof SDKError) {
      setError(err)
    } else {
      console.error('Unexpected error:', err)
    }
  }, [])

  const clearError = useCallback(() => setError(null), [])

  const canRetry = error
    ? ![
        SDKErrorCode.NotInitialized,
        SDKErrorCode.ModelNotFound,
        SDKErrorCode.WASMNotLoaded,
      ].includes(error.code)
    : false

  return { error, handleError, clearError, canRetry }
}
```

## Logging Errors

```typescript theme={null}
import { SDKLogger, LogLevel } from '@runanywhere/web'

SDKLogger.level = LogLevel.Error

try {
  const { stream } = await TextGeneration.generateStream(prompt)
  for await (const token of stream) {
    /* ... */
  }
} catch (err) {
  if (err instanceof SDKError) {
    console.error(`[${err.code}] ${err.message}`, err.details)
  }
}
```

## Related

<CardGroup cols={2}>
  <Card title="Configuration" icon="gear" href="/web/configuration">
    SDK configuration
  </Card>

  <Card title="Best Practices" icon="star" href="/web/best-practices">
    Optimization tips
  </Card>
</CardGroup>
