Ошибки
Категории ошибок GoRouter и OpenRouter, ограничения провайдеров и правила повторных запросов.
Формат ответа
{
"error": {
"message": "Alibaba: Превышен лимит запросов. Попробуйте чуть позже или выберите другого провайдера.",
"type": "rate_limit_exceeded",
"code": 502,
"metadata": {
"error_type": "rate_limit_exceeded",
"provider_name": "Alibaba"
}
}
}Для обработки ошибок сервиса модели используйте error.type: это категория причины, а не только HTTP-статус. Например, OpenRouter может вернуть общий 502, хотя вложенная ошибка провайдера сообщает о превышении лимита.
error.message— понятное сообщение на русском. Не сравнивайте его текст в коде.error.type— стабильная категория ошибки из справочника ниже или локальный код GoRouter.error.code— исходный строковый или числовой код OpenRouter. Для локальных ошибок совпадает сerror.type.error.metadata.error_type— нормализованная категория ошибки сервиса модели.error.metadata.provider_nameиprovider_code— имя провайдера и его код ошибки, если они доступны.Retry-After— минимальная задержка перед повтором, если её передал сервис.
Внутренние тела ошибок, ключи и заголовки провайдера не возвращаются. Если OpenRouter скрыл причину, GoRouter не может восстановить её: в ответе будет общая категория и безопасное сообщение.
HTTP-статусы
HTTP-статус сохраняется от OpenRouter. Исключение — распознанный отказ по приватности: он возвращается как 403 с кодом no_allowed_providers.
| HTTP | Значение | Действие |
|---|---|---|
| 400 | Неверный запрос | Исправить параметры или содержимое. |
| 401 | Ошибка авторизации | Проверить error.type: свой ключ или доступ сервиса модели. |
| 402 | Ограничение средств | Проверить error.type: баланс GoRouter или ограничение сервиса модели. |
| 403 | Нет разрешения | Проверить доступ, правила модели и приватность по конкретному коду. |
| 404 | Модель или ресурс не найдены | Проверить идентификатор и доступность. |
| 408 | Истекло время ожидания | Повторить позже, учитывая возможное выполнение запроса. |
| 412 | Не выполнены предварительные условия | Обновить данные перед повтором. |
| 413 | Слишком большой запрос | Уменьшить текст или вложения. |
| 422 | Запрос невозможно обработать | Проверить формат и совместимость параметров. |
| 429 | Превышен лимит | Использовать Retry-After и ограниченное число повторов. |
| 500 | Внутренняя ошибка | Повторить позже; подробности могут быть скрыты. |
| 502 | Некорректный ответ провайдера | Уточнить причину по error.type. |
| 503 | Провайдер недоступен или проверка приватности не завершена | Повторить позже по Retry-After, если он есть. |
| 504, 524 | Тайм-аут сервиса | Повторить позже, учитывая возможное выполнение запроса. |
| 529 | Провайдер перегружен | Подождать или выбрать другой маршрут. |
Другие статусы также возможны. Неизвестная причина получает error.type: "unmapped"; исходный статус сохраняется.
Ошибки и inference-авторизации
Если провайдер явно отклонил параметры до генерации и нет данных о выполнении или расходе,
GoRouter освобождает авторизацию: X-GoRouter-Billing-Status: released.
Один HTTP-статус 400 без подтверждённой причины недостаточен для освобождения.
При таймауте или обрыве соединения запрос мог уже выполняться: запрос остаётся на сверке
(pending) до получения стоимости. Через 35 минут авторизация перестаёт уменьшать доступный баланс,
но поздний подтверждённый счёт всё равно списывается и может создать долг. Не отправляйте повторные запросы
подряд только из-за ошибки таймаута в клиенте.
Категории ошибок сервиса модели
Контекст и токены
error.type | Значение и действие |
|---|---|
context_length_exceeded | Превышен размер контекста. Сократите историю или начните новый чат. |
max_tokens_exceeded | Достигнут лимит ответа. Увеличьте max_tokens / max_output_tokens в пределах возможностей модели. |
token_limit_exceeded | Превышен лимит токенов. Уменьшите запрос или лимит ответа. |
string_too_long | Один из текстовых фрагментов слишком длинный. Сократите его. |
Доступ и средства
error.type | Значение и действие |
|---|---|
authentication | Авторизация отклонена на стороне сервиса модели. Повторите позже или выберите другую модель. Это не означает, что ваш ключ GoRouter неверен. |
permission_denied | Сервис модели запретил запрос. Проверьте доступ к модели и ограничения запроса. |
payment_required | Ограничение средств на стороне сервиса модели. Это не ошибка вашего баланса GoRouter. Повторите позже или выберите другую модель. |
Лимиты и доступность
error.type | Значение и действие |
|---|---|
rate_limit_exceeded | Превышен лимит запросов или токенов в единицу времени. Подождите или выберите другого провайдера. |
provider_overloaded | Провайдер перегружен. Повторите позже или смените маршрут. |
provider_unavailable | Провайдер не смог вернуть корректный ответ. Повторите позже или выберите другую модель. |
timeout | Провайдер не успел ответить. Повторяйте с задержкой, учитывая возможное выполнение предыдущего запроса. |
server | Внутренняя ошибка сервиса модели. Повторите позже. |
Запрос и содержимое
error.type | Значение и действие |
|---|---|
invalid_request | Параметры не подходят модели. Проверьте запрос и поддерживаемые настройки. |
invalid_prompt | Недопустимое содержимое или формат сообщения. Проверьте текст и вложения. |
not_found | Модель или ресурс недоступны. Проверьте идентификатор. |
precondition_failed | Не выполнены условия запроса. Обновите данные перед повтором. |
payload_too_large | Запрос слишком большой. Уменьшите текст или вложения. |
unprocessable | Запрос невозможно обработать. Проверьте формат данных. |
content_policy_violation | Запрос или ответ отклонён правилами безопасности. Измените содержимое. |
refusal | Модель отказалась отвечать. Попробуйте другую формулировку. |
Изображения
error.type | Значение и действие |
|---|---|
invalid_image | Файл повреждён или не читается. Прикрепите другое изображение. |
image_too_large | Превышен размер файла или разрешение. Уменьшите изображение. |
image_too_small | Слишком маленькое разрешение. Используйте более крупное изображение. |
unsupported_image_format | Формат не поддерживается моделью. Преобразуйте файл в доступный формат. |
image_not_found | Изображение не найдено. Проверьте ссылку или прикрепите файл повторно. |
image_download_failed | Не удалось скачать изображение. Проверьте доступность ссылки или прикрепите файл напрямую. |
Неизвестная причина
unmapped — причина не относится к известным категориям или не раскрыта сервисом. Учитывайте HTTP-статус и не повторяйте запрос бесконечно.
Локальные ошибки GoRouter
Для этих ошибок error.code и error.type совпадают.
| Код | Значение и действие |
|---|---|
invalid_api_key | Ключ GoRouter отсутствует, неверен или недоступен. Проверьте заголовок Authorization. |
management_key_not_allowed | Management key нельзя использовать для генерации. Используйте inference key. |
insufficient_balance | Недостаточно средств в защищённом режиме. Ответ содержит ожидаемую цену и доступную сумму; параметры запроса GoRouter не уменьшает. |
balance_exhausted | Бюджет генерации закончился. Пополните баланс или уменьшите лимит ответа. |
outstanding_debt | Сначала погасите задолженность пополнением баланса. |
media_generation_in_progress | В аккаунте уже выполняется генерация изображения, аудио или видео. Дождитесь её завершения. |
billing_unbounded | Для выбранного маршрута и параметров нет достоверной оценки стоимости. Запрос не отправлен. |
billing_upstream_key_suspended | Финальные счета по затронутому upstream-ключу противоречат друг другу. Ключ отключён до ручной сверки; другие ключи и модели не блокируются. |
legal_acceptance_required | Перед следующим платным запросом примите новую редакцию пользовательского соглашения. |
key_limit_exceeded | Превышен лимит ключа GoRouter. Измените лимит в кабинете. |
generation_timeout | Генерация остановлена по таймауту. |
response_too_large | Готовый JSON-ответ превысил допустимый размер. Используйте streaming. |
invalid_request_error, unsupported_parameter | Некорректный запрос или неподдерживаемый параметр. Исправьте запрос. |
model_not_found | Модель не найдена или отключена. Выберите доступную модель. |
upstream_unreachable, upstream_error | Не удалось связаться с сервисом модели или получить ответ. Повторите позже. |
usage_unavailable | Не удалось определить стоимость результата. Повторите позже; не запускайте бесконечные повторы. |
video_job_not_found | Задача видео не найдена или принадлежит другому пользователю. Проверьте идентификатор. |
video_not_settled | Результат видео пока нельзя скачать. Повторно проверьте состояние задачи. |
internal_error | Внутренняя ошибка GoRouter. Повторите позже. |
Приватность
| HTTP | Код | Значение |
|---|---|---|
| 403 | privacy_policy_violation | Явный выбор в provider.only или provider.order противоречит профилю. |
| 403 | no_allowed_providers | Для запроса не осталось разрешённых провайдеров. |
| 503 | privacy_policy_unavailable | Не удалось проверить или применить правила. Запрос не отправлен; возможен повтор с задержкой. |
| 400 | invalid_privacy_settings | Некорректные настройки в кабинете; не относится к публичному inference API. |
| 409 | privacy_settings_conflict | Настройки изменены в другой вкладке кабинета. Загрузите актуальную версию. |
При privacy_policy_violation и no_allowed_providers проверьте настройки приватности. Не каждый 403 связан с приватностью. При распознанном отказе по политике приватности резерв освобождается без списания. Подробнее: Приватность и провайдеры.
Защита чувствительных данных
| HTTP | Код | Значение |
|---|---|---|
| 400 | sensitive_data_rejected | Ключ настроен отклонять запросы с найденными категориями. |
| 413 | sensitive_data_too_large | Анализируемый текст превышает 1 МиБ. |
| 503 | sensitive_data_unavailable | Локальная проверка недоступна; исходный запрос не отправлен провайдеру. |
Ошибки не содержат найденные значения. Подробнее: Защита чувствительных данных.
Ошибки при HTTP 200 и в потоке
Успешный HTTP-статус не гарантирует успешную генерацию. Проверяйте содержимое ответа:
- Chat Completions:
errorв корне илиchoices[].error, в том числе приfinish_reason: "error". - Responses:
errorв ответе илиresponse.errorв событияхresponse.failed/response.error. - SSE: ошибка может прийти после нескольких токенов при уже открытом HTTP 200.
GoRouter сохраняет оболочку ответа и уже полученный текст. Категория доступна в соответствующем объекте error.type. Обычный finish_reason: "length" сам по себе не преобразуется в ошибку.
data: {"choices":[{"index":0,"delta":{"content":"Начало ответа"}}]}
data: {"error":{"code":429,"type":"rate_limit_exceeded","message":"Превышен лимит запросов. Попробуйте чуть позже или выберите другого провайдера.","metadata":{"error_type":"rate_limit_exceeded"}},"choices":[{"index":0,"delta":{},"finish_reason":"error"}]}
data: [DONE]Не перезапускайте генерацию автоматически после частичного ответа: повтор создаёт новый запрос и может привести к дополнительной оплате. Разрыв соединения или тайм-аут не гарантирует остановку работы провайдера. См. Streaming.
Повторные запросы
Для временных лимитов и сбоев используйте ограниченное число попыток с увеличивающейся задержкой. Учитывайте Retry-After: он может содержать число секунд или HTTP-дату. Для 400, 401, 402, 403 сначала устраните причину. Если 502 содержит более точную категорию, решение о повторе принимайте по ней.
function retryDelayMs(response: Response): number | null {
const value = response.headers.get("retry-after");
if (!value) return null;
if (/^\d+$/.test(value)) return Number(value) * 1000;
const until = Date.parse(value);
return Number.isNaN(until) ? null : Math.max(0, until - Date.now());
}
// Для обычного JSON-ответа. SSE разбирайте по событиям.
const payload = await response.json();
const error = payload.error ?? payload.response?.error
?? payload.choices?.find((choice: { error?: unknown }) => choice.error)?.error;
if (!response.ok || error) {
console.error(error?.type ?? "unknown", error?.message ?? "Ошибка запроса");
const delayMs = retryDelayMs(response);
// Решение о повторе зависит от причины и наличия частичного результата.
}Справочник соответствует категориям ошибок OpenRouter и HTTP-ошибкам TypeScript SDK.