Overview
VIZOCHOK uses machine-readable error codes throughout the system. The backend sends structured error objects with a code field, and the SDK maps these codes to localized human-readable messages in the widget’s configured language (Ukrainian or English).
The backend never sends user-facing text. It sends a code, and the client renders the appropriate message.
WebSocket Error Codes
These errors are sent as {"type": "error", "code": "..."} messages over the WebSocket connection.
Rate Limiting Errors
| Code | Description | Retry | Additional Fields |
|---|
rate_limit_exceeded | Too many messages in the current window (10 per 60 seconds per connection). | Yes | retry_after (seconds) |
user_message_limit | User has reached the daily message limit (default: 200/day). | No | limit (max count) |
user_conversation_limit | User has reached the daily conversation limit (default: 20/day). | No | limit (max count) |
tenant_daily_token_limit | Tenant has exceeded the daily token budget (default: 500,000 tokens/day). | No | — |
tenant_monthly_token_limit | Tenant has exceeded the monthly token budget (default: 10,000,000 tokens/month). | No | — |
Session Errors
| Code | Description | Retry |
|---|
agent_busy | Another request is already being processed for this conversation. The agent uses a Redis lock to prevent concurrent processing. | Yes |
session_token_limit | The conversation has exceeded the per-session token limit. The user should start a new conversation. | No |
max_rounds_exceeded | The agent’s tool chain exceeded the maximum number of iterations. The user should simplify their request. | No |
| Code | Description | Additional Fields |
|---|
message_too_large | Message exceeds the 64 KB size limit. Checked both client-side and server-side. | max_size (bytes) |
invalid_json | The message could not be parsed as valid JSON, or failed Pydantic validation. | — |
System Errors
| Code | Description |
|---|
internal_error | An unexpected server error occurred. Also sent on agent processing timeout (120s). |
no_catalog_data | The tenant’s product catalog has no active products. Sent on the first message of a new conversation. |
SDK Client-Side Error Codes
These errors are generated by the widget SDK itself (not from the server) and delivered through the onError callback.
| Code | Description |
|---|
auth_timeout | The server did not respond with auth_ok within 10 seconds of the auth message. |
auth_error | Authentication failed. The WebSocket was closed with a 4001-4004 close code. |
ws_error | WebSocket connection error (network failure, DNS resolution failure, etc.). |
message_too_large | Client-side check: message exceeds 64 KB before sending (prevents unnecessary round-trip). |
queue_full | The client-side message queue has reached its maximum capacity (50 messages). |
max_reconnect | Maximum reconnection attempts (30) exhausted without establishing a connection. |
connection_lost | Connection was lost while the server was streaming a response. The partial text is preserved. |
WebSocket Close Codes
When the server closes the WebSocket connection, it uses these custom close codes:
| Code | Reason | Description |
|---|
4001 | Auth timeout / Invalid auth | First message was not an auth message, auth timed out, or the message failed validation. Also used for invalid/expired API keys. |
4002 | API key lacks chat scope | The API key is valid but does not have the chat scope. |
4003 | Origin not allowed / Tenant deactivated | WebSocket origin is not in the allowed origins list, or the tenant account is deactivated. |
4004 | Tenant LLM not configured | The tenant exists but has no LLM provider configured. |
4005 | Auth timeout (client) | Client-side auth timeout — sent by the SDK if no auth_ok is received within 10 seconds. |
4008 | Heartbeat timeout | No pong received within 60 seconds. The connection is considered dead. |
4029 | Too many connections | Exceeded the maximum concurrent WebSocket connections per API key (3). |
REST API Error Responses
REST API endpoints (admin panel, catalog management) return standard HTTP error responses:
{
"detail": "Human-readable error message"
}
Common HTTP Status Codes
| Status | Usage |
|---|
400 | Invalid request body or parameters (e.g., invalid webhook URL). |
401 | Invalid or expired credentials (API key, JWT session). |
403 | Insufficient permissions (e.g., non-owner trying to manage users). |
404 | Resource not found (tenant, user, API key). |
409 | Conflict (e.g., duplicate email, cannot deactivate yourself, last active key). |
422 | Validation error (e.g., password too short, Pydantic validation failure). |
429 | Too many login attempts. |
Error Localization
The SDK maintains built-in translations for all server error codes:
{
rate_limit_exceeded: 'Too many messages. Please wait a moment.',
user_message_limit: 'Daily message limit reached.',
user_conversation_limit: 'Daily conversation limit reached.',
tenant_daily_token_limit: 'Service temporarily unavailable. Please try again later.',
tenant_monthly_token_limit: 'Service temporarily unavailable. Please try again later.',
agent_busy: 'Assistant is processing a previous request.',
message_too_large: 'Message is too long. Please shorten it.',
invalid_json: 'Message format error.',
internal_error: 'Something went wrong. Please try again.',
max_rounds_exceeded: 'Request was too complex. Please simplify your question.',
session_token_limit: 'Conversation is too long. Please start a new one.',
no_catalog_data: 'Product catalog is not loaded yet.',
}
Russian language ('ru') uses the Ukrainian translations, since the AI always responds in Ukrainian for Russian-language input.
Error Handling Best Practices
const widget = new VIZOCHOKWidget({
apiKey: 'pk_your_key',
storeId: 'your-store',
onError: (error) => {
switch (error.code) {
// Auth errors -- cannot recover without config change
case 'auth_error':
case 'auth_timeout':
console.error('Widget auth failed:', error.message);
break;
// Rate limits -- temporary, auto-recovers
case 'rate_limit_exceeded':
case 'user_message_limit':
// Widget shows the error inline; no action needed
break;
// Tenant limits -- contact support
case 'tenant_daily_token_limit':
case 'tenant_monthly_token_limit':
reportToAdmin('VIZOCHOK token limit reached');
break;
// Connection issues -- widget auto-reconnects
case 'ws_error':
case 'connection_lost':
// No action needed
break;
// Fatal connection failure
case 'max_reconnect':
showFallback('Chat is temporarily unavailable');
break;
default:
console.warn('VIZOCHOK error:', error.code, error.message);
}
},
});
General Guidelines
- Do not suppress errors silently. At minimum, log them for debugging.
- Tenant limit errors are your concern. Monitor
tenant_daily_token_limit and tenant_monthly_token_limit and upgrade your plan before hitting limits.
- The widget handles display. All error codes are rendered as user-friendly messages inside the chat panel automatically. The
onError callback is for your application logic, not for displaying errors to users.
- Connection errors auto-recover. The SDK has built-in reconnection with exponential backoff (1s to 10s, up to 30 attempts). You do not need to implement your own reconnection logic.
- The
retry_after field on rate_limit_exceeded tells you how many seconds to wait. The widget displays a countdown timer automatically.