После подключения Codex CLI к собственному API ошибки чаще всего сосредоточены на шести уровнях: учётные данные, путь, модель, лимиты, контекст и локальная песочница. При виде красного сообщения менять модель или переустанавливать инструмент — значит превратить десятиминутную проблему в полдня. Эффективнее зафиксировать переменные: один ключ, один Base URL и один ID модели, менять за раз только один пункт. Статья разбирает ошибки по кодам состояния и приводит расположение журналов, команды диагностики и пример обработки.

Примечание: OpenAI и Codex — товарные знаки OpenAI, Inc. Статья носит технический характер и не подразумевает аффилированности или сотрудничества с указанной компанией. Конфигурация и текст меняются от версии к версии; сверяйтесь с официальной документацией и текущей версией. Модели и цены смотрите на странице «Модели и цены».

1. Сначала смотрите на код состояния, потом меняйте конфигурацию

Симптом Обычное значение Что проверить сначала Повторять ли
401 Ключ отсутствует, неверен или недействителен Переменная env_key, статус ключа, баланс Нет
403 У ключа нет прав или сработала политика Права на модель, статус аккаунта, командные политики Нет
404 Неверный путь или интерфейс не существует Base URL, поддержка /responses Нет
model not found Неверный ID модели или модель не подключена Идентификатор модели, права аккаунта Нет
429 Превышена частота, параллельность или квота Расход, общий ключ, настройки повторов Да, с задержкой
400 context_length_exceeded Контекст превышает лимит модели Объём входа, вывод инструментов, сжатие Да, изменив запрос
Сбой песочницы или подтверждения Локальные границы прав Режим песочницы, каталоги записи, политика подтверждений Да, изменив политику
Таймаут или обрыв потока Прокси, TLS, простой, перегрузка сервера Сетевой путь, таймауты и повторы Зависит от случая

Рекомендуемый порядок проверки:

  1. Выполните codex doctor в каталоге проекта: установка, конфигурация, авторизация и среда запуска.
  2. В сессии посмотрите /status: модель, политика подтверждений, доступные для записи каталоги и расход токенов.
  3. Через /debug-config проверьте итоговые действующие значения, чтобы не менять файл, который не загружается.
  4. Проверьте Base URL, ключ и модель минимальным запросом.
  5. И только потом меняйте модель, контекст или политику песочницы.

2. 401 и 403: ключ не попал в процесс

Пользовательский provider Codex задаёт имя переменной через env_key, например:

[model_providers.zsqh]
name = "ZSQH AI Gateway"
base_url = "https://ai.zhongshangqihang.com/v1"
env_key = "ZSQH_API_KEY"
wire_api = "responses"

Правильная конфигурация не означает, что процесс видит ключ. Частые причины: имя переменной в оболочке отличается от env_key; переменная экспортирована в терминале A, а Codex запущен в терминале B; приложение из графического интерфейса не унаследовало окружение; вокруг ключа пробелы, перевод строки или кавычки; ключ принадлежит другой платформе или среде; ключ удалён, отключён или баланс исчерпан.

В среде без графического интерфейса ключ можно передать через CODEX_API_KEY, но не держите одновременно несколько источников — иначе трудно понять, какой ключ реально используется. 403 чаще связан с правами или политикой: сначала изучите тело ответа, затем консоль шлюза, и не повторяйте запрос вслепую.

3. 404 и model not found: адрес, протокол и ID модели

Текущий пользовательский provider Codex принимает только wire_api = "responses", поэтому запрос уходит на /v1/responses. Отсюда несколько частых 404:

  • В base_url пропущен /v1, и запрос попадает на маршрут веб-страницы.
  • В base_url уже есть /responses, клиент добавляет его снова — путь дублируется.
  • Шлюз предоставляет только /v1/chat/completions и не реализует протокол Responses.
  • Опечатка в домене или в качестве API-адреса указан адрес консоли.

Обычно base_url указывается до /v1; не собирайте полный путь самостоятельно. Если модели нет, разные шлюзы могут вернуть 404 или 400, поле кода часто model_not_found, но ориентируйтесь прежде всего на тело ответа. ID модели должен полностью совпадать с идентификатором API на странице «Модели и цены», включая регистр, дефисы и суффикс версии.

codex debug models выводит локальный или встроенный каталог и не означает, что шлюз реально открыл эти модели. Проверьте также соответствие model_provider имени [model_providers.xxx]; при несовпадении Codex может откатиться на provider по умолчанию, и это выглядит как «конфигурация не применилась».

4. 429: сначала снизьте параллельность, потом говорите о повторах

429 означает превышение частоты, параллельности или квоты токенов. Codex постоянно читает файлы и выполняет команды, поэтому срабатывает чаще обычного чата. Типичные ситуации: превышены запросы или токены в минуту; несколько человек используют один ключ; в большом репозитории подряд читается множество файлов; повторы идут без задержки и создают лавину; длинные контексты занимают всю параллельность.

В конфигурации provider у Codex есть request_max_retries (по умолчанию 4) и stream_max_retries (по умолчанию 5). Они повышают устойчивость, но при постоянных 429 увеличивают число запросов; на время диагностики их можно временно уменьшить.

Различайте ограничение частоты и нехватку средств: если в теле ошибки есть поле вроде insufficient_quota, повторять бессмысленно — проверьте баланс или квоту в консоли. При настоящем ограничении смотрите Retry-After; если заголовка нет, используйте экспоненциальную задержку со случайным разбросом. Ключи по проектам или людям позволяют быстрее найти источник, чем один общий ключ.

5. Превышение контекста: сначала уменьшите вход, потом меняйте модель

Типичный код превышения контекста — context_length_exceeded, в тексте может встречаться «maximum context length». Запрос Codex включает не только ваш вопрос, но и системный промпт, AGENTS.md, прочитанные файлы, вывод инструментов и историю. В длинной задаче вывод каждого предыдущего шага остаётся в контексте.

Рекомендуемый порядок:

  1. Сузьте рабочий каталог, чтобы Codex читал только нужные модули.
  2. Ограничьте в промпте набор файлов, избегайте сканирования всего репозитория.
  3. Исключите артефакты сборки, каталоги зависимостей, журналы и файлы с ключами.
  4. Ограничьте число токенов на вывод одного инструмента через tool_output_token_limit.
  5. Начните новую сессию и продолжите с кратким резюме уже сделанного.
  6. Только при реальной необходимости переходите на модель с более длинным контекстом.

model_context_window должен соответствовать реальному окну: завышенное число всё равно будет отклонено сервером; слишком высокий model_auto_compact_token_limit может сначала упереться в жёсткий лимит. Фактическое окно уточняйте в официальной документации и на странице цен.

6. Сбой песочницы и подтверждений: это не ошибка API

У Codex три режима песочницы: read-only, workspace-write и danger-full-access. read-only не позволяет менять файлы; workspace-write разрешает запись только внутри доступных корней и может настраивать сеть; danger-full-access снимает файловые и сетевые границы и подходит только для контролируемой среды.

Типичные проявления — Operation not permitted, Permission denied или запрос подтверждения посреди выполнения. Сначала посмотрите в /status режим и доступные каталоги, затем проверьте, не находится ли проект вне каталога, нужен ли команде сетевой доступ и есть ли у неинтерактивного codex exec точка подтверждения.

По политике подтверждений текущие версии поддерживают on-request, never и granular. Старый approval_policy = "untrusted" больше не поддерживается и может помешать запуску Codex; on-failure также устарел. В CI можно явно указать codex exec --sandbox workspace-write; для задач только на чтение — --sandbox read-only --ask-for-approval never. Не включайте danger-full-access просто для удобства.

7. Таймауты и обрыв потока: прокси, TLS и простой

Потоковые запросы чувствительнее к сетевому пути. Корпоративный прокси, TLS-перехват, переключение VPN и нестабильный выход могут выглядеть как «запрос отправлен, но первого токена всё нет» или обрыв посередине.

stream_idle_timeout_ms по умолчанию 300000 мс (пять минут). У reasoning-моделей первый токен приходит медленнее, слишком низкое значение даст ложные срабатывания; если прокси обрывает простаивающее соединение через 60 секунд, увеличение таймаута клиента не поможет — нужно проверять весь путь.

Для самоподписанного CA или TLS-перехвата можно указать пакет сертификатов PEM через CODEX_CA_CERTIFICATE; SSL_CERT_FILE используется только как резерв, если первая переменная не задана. Не отключайте проверку сертификатов целиком. После таймаута отправьте один минимальный непоточный запрос, убедитесь в доступности API и только затем воспроизводите проблему в Codex.

8. Журналы и диагностика: сначала доказательства, потом конфигурация

Каталог журналов Codex задаётся log_dir, по умолчанию это $CODEX_HOME/log. Текстовый codex-tui.log создаётся дополнительно только при явно заданном log_dir; для диагностики рекомендуется включить его в пользовательской конфигурации.

Основные точки диагностики:

  • codex doctor: отчёт об установке, конфигурации, авторизации, среде выполнения и состоянии терминала.
  • /status: модель, политика подтверждений, доступные для записи каталоги и расход токенов в текущей сессии.
  • /debug-config: источники конфигурации, приоритеты и итоговые действующие значения.
  • codex exec --json: поток событий JSON при неинтерактивном выполнении.
  • RUST_LOG: уровень подробности журналов, например codex_core=debug,codex_tui=debug; codex exec по умолчанию показывает только уровень error.

При диагностике сопоставляйте итоговые значения конфигурации с фактическим запросом: Base URL, путь /responses, имя модели, политику подтверждений. Многие случаи «настройка не применилась» связаны с неверным расположением файла или неперечитанными переменными окружения.

9. Многоразовый пример обработки ошибок

Пример ниже предназначен для вашего собственного скрипта вызова шлюза и не заменяет встроенные повторы Codex CLI. Принцип: ошибки авторизации и пути не повторять, при 429 и 5xx делать задержку, при ошибке контекста сразу менять запрос.

import random
import time

import httpx

RETRYABLE = {429, 500, 502, 503, 504}


def call_gateway(payload: dict, key: str, url: str):
    for attempt in range(4):
        try:
            resp = httpx.post(
                url,
                json=payload,
                headers={"Authorization": f"Bearer {key}"},
                timeout=httpx.Timeout(180.0, connect=10.0),
            )
        except httpx.TimeoutException:
            if attempt == 3:
                raise
            time.sleep(min(30, 2 ** attempt) + random.random())
            continue

        # Ошибки авторизации, прав, пути и модели: меняйте конфигурацию, не повторяйте
        if resp.status_code in (401, 403, 404):
            raise RuntimeError(f"{resp.status_code}: {resp.text[:300]}")

        if resp.status_code == 400:
            body = resp.text.lower()
            if "context" in body or "maximum context" in body:
                raise RuntimeError("Превышен контекст: сократите вход или начните новую сессию")
            raise RuntimeError(f"Ошибка формата запроса: {resp.text[:300]}")

        if resp.status_code in RETRYABLE:
            if "insufficient_quota" in resp.text:
                raise RuntimeError("Недостаточная квота: проверьте баланс, не повторяйте")
            retry_after = float(resp.headers.get("Retry-After", 2 ** attempt))
            time.sleep(min(30, retry_after) + random.random())
            continue

        resp.raise_for_status()
        return resp.json()

    raise RuntimeError("Попытки исчерпаны")

Код не обрабатывает песочницу и подтверждения — это локальный уровень выполнения. Разделяйте ошибки API и локальные ошибки прав: так диагностика идёт намного быстрее.

Частые вопросы

Ключ нормально работает на сайте, а Codex возвращает 401?

Уточните, какую переменную читает Codex, и экспортируйте её в той же оболочке, из которой запускается Codex. Приложения из графического интерфейса часто не видят только что заданные переменные; перезапустите приложение или проверьте авторизацию через codex doctor.

404 обязательно означает, что модель снята с публикации?

Нет. Codex использует протокол Responses: неверный путь и отсутствие /v1/responses на шлюзе тоже дают 404. Сначала убедитесь, что адрес указан до /v1, затем сверьте ID модели.

При 429 стоит увеличить число повторов?

Не рекомендуется. Постоянные 429 означают, что лимит уже превышен, и увеличение повторов лишь добавит запросов. Снизьте параллельность, разделите ключи, посмотрите Retry-After и определите, это ограничение частоты или нехватка средств.

Может ли Codex работать через Chat Completions?

Сейчас принимается только wire_api = "responses". Для endpoint только с Chat Completions нужен слой преобразования протокола или другой клиент; не пытайтесь обойти это установкой старой версии.

Можно ли просто отключить ошибки песочницы?

Можно перейти на workspace-write и настроить доступные каталоги либо использовать более широкий режим в контролируемой среде, но danger-full-access не стоит делать режимом по умолчанию. Сначала посмотрите /status и определите границы.

Что дальше

В диагностике ошибок Codex порядок важнее приёмов: сначала код состояния и тело ответа, затем codex doctor и /debug-config для проверки конфигурации, и только потом модель или песочница. Если нужны единые ключи, расход и вход к моделям, можно зарегистрироваться в ZSQH AI Gateway; модели и доступные интерфейсы смотрите на странице «Модели и цены».

Читайте также: