---
title: Errors
slug: web-view-sdk-errors
createdAt: 2026-11-03T10:14:20.176Z
---

The calls that wait for the chat report a failure as an error you can catch: `sendMessage`, `authenticate` and `deauthenticate` on iOS and Android, and in Flutter and React Native every call that returns a future or a promise. The calls that return nothing on iOS and Android, such as `displayChat`, `triggerDialogue` and `setNewContext`, report a refused call in the [Logging and Crash Reporting](docId\:CvwcNYrweCJNxeWTZCRY1) instead

## Error codes

| Meaning                                                                | iOS `KindlyWebViewError` | Android `KindlyWebViewException` | Flutter `KindlyWebViewErrorCode` | React Native `code` |
| ---------------------------------------------------------------------- | ------------------------ | -------------------------------- | -------------------------------- | ------------------- |
| `start` was not called, or `kill` ran since                            | `notStarted`             | `NotStarted`                     | `notStarted`                     | `NOT_STARTED`       |
| No chat page is loaded. Show the chat first                            | `chatNotReady`           | `ChatNotReady`                   | `chatNotReady`                   | `CHAT_NOT_READY`    |
| An argument was refused. The error names the argument, never its value | `invalidArgument(_:)`    | `InvalidArgument`                | `invalidArgument`                | `INVALID_ARGUMENT`  |
| `authenticate()` was called, but `start` got no auth provider          | `noAuthProvider`         | `NoAuthProvider`                 | `nativeError`                    | `NATIVE_ERROR`      |
| The chat page did not answer in time                                   | `timeout`                | `Timeout`                        | `nativeError`                    | `NATIVE_ERROR`      |
| The chat widget refused or failed the call                             | `widgetError(code:)`     | `WidgetError`                    | `nativeError`                    | `NATIVE_ERROR`      |
| This device or app cannot run the chat                                 | `unsupported`            | `Unsupported`                    | `unsupported`                    | `UNSUPPORTED`       |
| Android only: there was no context to show the chat from               |                          |                                  | `noActivity`                     | `NO_ACTIVITY`       |

The widget error's `code` is `unknown_command`, `widget_error` or `unknown`, never text from the page

## Handling an error

::::Tabs
:::Tab{title="iOS"}
```swift
Task {
    do {
        try await KindlyWebViewSDK.sendMessage("Where is my order?")
    } catch let error as KindlyWebViewError {
        switch error {
        case .chatNotReady:
            KindlyWebViewSDK.displayChat()
        case let .invalidArgument(name):
            print("Kindly refused \(name)")
        default:
            print(error.localizedDescription)
        }
    } catch {
        print(error.localizedDescription)
    }
}
```

`KindlyWebViewError` can gain cases in a later version, so give a `switch` over it a `default` or `@unknown default` case. `endChat()` and `kill()` are `async` and never throw
:::

:::Tab{title="Android"}
```kotlin
lifecycleScope.launch {
    try {
        KindlyWebViewSDK.sendMessage("Where is my order?").await()
    } catch (e: KindlyWebViewException.ChatNotReady) {
        KindlyWebViewSDK.launchChat(this@MainActivity)
    } catch (e: KindlyWebViewException) {
        Log.w("Chat", "Kindly call failed: ${e.message}")
    }
}
```

The `Deferred` results fail with a subclass of the sealed `KindlyWebViewException`. `InvalidArgument.argument` names the argument and `WidgetError.code` holds the widget's code
:::

:::Tab{title="Flutter"}
```dart
try {
  await KindlyWebViewSDK.sendMessage('Where is my order?');
} on KindlyWebViewException catch (error) {
  if (error.errorCode == KindlyWebViewErrorCode.chatNotReady) {
    await KindlyWebViewSDK.displayChat();
  } else {
    debugPrint('Kindly call failed: ${error.code}');
  }
}
```

A failed call throws a `KindlyWebViewException`. `code` is the raw code, such as `CHAT_NOT_READY`, and `errorCode` the enum value, `unknown` for a code this version does not know. An argument that is blank or in the wrong format throws an `ArgumentError` before anything reaches the native SDK
:::

:::Tab{title="React Native"}
```typescript
import { KindlyWebViewError, KindlyWebViewSDK } from '@kindly-ai/react-native-webview';

try {
  await KindlyWebViewSDK.sendMessage('Where is my order?');
} catch (error) {
  if (error instanceof KindlyWebViewError && error.code === 'CHAT_NOT_READY') {
    await KindlyWebViewSDK.displayChat();
  } else {
    throw error;
  }
}
```

Calls that return a promise reject with a `KindlyWebViewError`, and the setters, such as `setNewContext` and `setDelegate`, throw it. An argument in the wrong format is refused with `INVALID_ARGUMENT` before anything reaches the native SDK
:::
::::

The error messages never contain a token, a chat id, a URL or message text, so they are safe to log
