Когда не работает
This page is in Russian.
По симптому. Каждый случай — то, что видно на экране, и что с этим делать.
Если симптома здесь нет, начните с --trace: он показывает, дошёл ли запрос до MAX и что
ответили, не раскрывая содержимого (diagnostics.md).
По коду возврата
| Код | Имя | Что обычно значит |
|---|---|---|
1 | generic_failure | опечатка в названии команды или сбой в самом max |
2 | validation_error | значение или сочетание опций, которых max не принимает; имя подходит нескольким чатам |
3 | configuration_error | ошибка в config.json, или локальную копию записала более новая версия |
4 | authentication_error | нет входа, сессию завершили, или ключница недоступна |
5 | permission_error | профиль только для чтения или действие не в его allow |
6 | not_found | нет такого чата, сообщения или человека; в локальной копии ещё пусто |
7 | confirmation_required | чата нет в списке получателей, или действие ждёт подтверждения, а ответить некому |
8 | rate_limited | лимит профиля в час, или MAX просит подождать |
9 | timeout | MAX не ответил вовремя, или --timeout остановил команду |
10 | network_error | MAX недоступен отсюда |
11 | provider_error | MAX отказал в запросе |
12 | provider_unavailable | сбой на стороне MAX |
13 | invalid_response | ответ, который max не смог прочитать |
14 | outcome_unknown | связь оборвалась после отправки: сообщение могло уйти |
130 | cancelled | нажали Ctrl-C или ответили «нет» на вопрос |
Сначала — max doctor
max doctorПечатает то, от чего зависит любая команда, не подключаясь к MAX (если не указан --online): есть ли токен и откуда,
какая запись в ключнице и не сдвинули ли её переменные окружения, сколько было входов и когда
последний, все профили на этой машине — личный аккаунт, бот или оба, — версия локальной копии против той, что понимает эта
сборка, каталог запусков и какой версией веб-клиента MAX max представляется — с датой, когда её
прочитали. Если этой дате больше 60 дней, max doctor предупредит: MAX может перестать принимать
старую версию, и тогда поможет обновление max.
Он отвечает и тогда, когда всё сломано — это единственный случай, когда его запускают.
Профиль без сессии не ошибка, а строка в ответе; код возврата остаётся 0.
Токен не печатается никогда — только «есть» и «откуда».
У профиля бота max <имя> doctor показывает токен бота (откуда он), сколько чатов бот видел и где
лежат файлы профиля: состояние, кеш, записи запусков, файлы ботов, журнал отправок и общее
хранилище сообщений.
Ещё он показывает, чем запущен max (Node или Bun, и где), каким менеджером пакетов поставлен,
какую команду max найдёт новый терминал, грузятся ли ключница и SQLite и скачана ли модель речи.
Если каталог с командой max не на PATH, max doctor печатает точные команды, которые его туда
добавят: на Windows — для PowerShell, на Linux и macOS — строку export.
Проверка со входом в MAX
max doctor --onlineОдин вход, один чат из списка, затем сервер MCP запускается так, как его запускает клиент, и
отвечает списком инструментов. Ничего не отправляет и ничего не отмечает прочитанным. Вход
засчитывается в лимит MAX на входы, поэтому при ошибке он не повторяется. Если какая-то часть не
прошла, код возврата — не 0.
Если у профиля есть токен бота, --online ещё спрашивает у Bot API, чей это токен, и печатает имя
и id бота. Если личного токена нет, вход в MAX не делается.
max не находится после установки
Установка прошла, а терминал отвечает, что команды max нет. Узнать причину можно без неё:
npx @leemour/max-cli doctorСтрока max on PATH покажет, найдена ли команда, а заметка ниже — что сделать.
Windows. npm кладёт команду в %APPDATA%\npm. Если этого каталога нет в PATH, max doctor,
запущенный после установки, напечатает две строки PowerShell: первая чинит текущее окно, вторая —
все новые. Проверить вручную:
npm prefix -g
$env:Path -split ';'Первая команда называет каталог, вторая — что сейчас в PATH. Если каталог в списке есть, а max
всё равно не находится, закройте и откройте терминал: окно, открытое до установки Node, не видит
новый PATH.
PowerShell отвечает «running scripts is disabled on this system». npm кладёт рядом max.ps1
(и npx.ps1), а PowerShell по умолчанию запрещает скрипты. Либо запускайте max.cmd и
npx.cmd — они работают всегда (npx.cmd @leemour/max-cli doctor), — либо разрешите скрипты для
своей учётной записи:
Set-ExecutionPolicy -Scope CurrentUser RemoteSignedLinux и macOS. Каталог команд npm — $(npm prefix -g)/bin. max doctor напечатает строку
export PATH=…; её нужно дописать в ~/.zshrc или ~/.bashrc.
На PATH другой max. Если раньше в PATH стоит чужая программа с тем же именем, max doctor
назовёт её путь. Вызывайте нашу по полному пути или поставьте её каталог раньше.
«no session for profile "default"»
{"error":{"code":"authentication_error","message":"no session for profile \"default\" — run `max session start`"}}Код возврата 4. Токена для этого профиля нет — либо не входили, либо вошли в другой профиль,
либо вошли с другими переменными каталогов.
max session start # войти
max personal chats list # или назвать профиль, в который входили⚠ Самая частая причина, когда токен точно есть: MAX_CONFIG_DIR задана в одном окне терминала и
не задана в другом. Эти переменные переносят и запись в ключнице, поэтому сессия, сохранённая с
ними, невидима без них. Проверьте env | grep MAX_.
«profile "shop" is a bot»
{"error":{"code":"authentication_error","message":"profile \"shop\" is a bot — its commands are `max shop bot …`; `max shop session start` would add a personal account to it"}}Личная команда запущена на профиле бота. Команды бота начинаются с bot:
max shop bot chats list
max shop bot messages list -100max shop session start не нужен, если вы не хотите держать под этим именем ещё и личный аккаунт.
max shop doctor покажет, что у профиля есть.
«no token found for profile "default", although it has logged in on this machine»
Код возврата 4. Профиль на этом компьютере уже входил, но токен не читается. Почти всегда это
хранилище паролей, до которого max не достучался: команда запущена из cron, по ssh или из
другого окружения без XDG_RUNTIME_DIR. Не входите заново — это добавит в аккаунт ещё одно
устройство, а в следующий раз из того же окружения токен снова не прочитается.
max doctor покажет, видит ли он токен; как настроить cron — в recipes.md.
«MAX refused this profile's last login for too many attempts»
Код возврата 8. MAX отказал во входе, потому что попыток было слишком много. max запомнил это
и до указанного времени сам не входит: ни одна команда, ни max session start, ни фоновый сервер.
Пауза растёт с каждым отказом подряд: 1 минута, 5 минут, 30 минут, час, 6 часов, дальше сутки.
Удачный вход её сбрасывает.
Подождите. Вход раньше срока — ещё одна попытка, которую MAX засчитает, а повторные
попытки после такого отказа держат аккаунт заблокированным. Если вход идёт по расписанию, сделайте
его реже. max doctor покажет, до какого времени пауза.
Фоновый сервер (max serve, max server start) на любом отказе во входе останавливается, а не
пробует снова. Сеть, которая пропала, он по-прежнему ждёт и подключается заново.
Команда отвечает, но профиль не тот
Первое слово читается как профиль, если оно не команда. Поэтому опечатка в имени команды превращается в имя профиля:
"chat" is not a command, so it was read as a profile name — and no command followed it.Команда называется chats, во множественном числе. max --help перечисляет все.
«is not a valid config»
{"error":{"code":"configuration_error","message":"…/config.json is not a valid config:\n profiles.default.limitt: unknown setting — the known ones are limit, timeoutMs, color, record, keepRunsForDays, readOnly, allow, sendsPerHour, senderColors, serve, mcpTools"}}Код 3. В файле настроек поле, которого нет в схеме — почти всегда опечатка, и сообщение
называет её путь. Отвергается намеренно: молча проигнорированное поле стоит полдня недоумения.
Список полей — configuration.md.
«--limit takes a whole number from 1 upwards, not "abc"»
Код 2. То же для --page. Без этой проверки нечисловое значение тихо обрезало бы список до пустого.
«--all and --page ask for different things; use one or the other»
Код 2. Переданы оба. Отказ, а не выбор одного из них: какой бы ни победил, узнать об этом
можно было бы только по неверному ответу.
«--before-time takes an ISO 8601 time or 30m, 2h, 1d ago»
Код 2. --before-time или --after-time не понял значение. Он принимает время в ISO 8601 или
«сколько назад»:
max messages list 0 --before-time 2026-09-20T01:00:00Z
max messages list 0 --before-time 2hId сообщения — в --before-id: время берётся из самого id, читать чат раньше не нужно.
«--at-time takes a time like 2026-09-25T09:00 or a delay like 30m, 2h, 1d»
Код 2. --at-time — местное время или задержка от сейчас в минутах, часах или днях, но не в
секундах. Не раньше чем через минуту и не позже чем через год.
«--timeout takes a duration with a unit — 30s, 2m or 500ms»
Код 2. --timeout и MAX_TIMEOUT принимают ms, s или m. Часов нет: два часа — это
120m.
Команда висит
Соединение установлено, ответа нет. Через таймаут будет код 9 и timeout.
max chats list --traceЕсли видна строка → без парной ← — запрос ушёл и не вернулся: это сеть или MAX, не программа.
Ограничить можно с двух сторон, и это разные вещи:
max chats list --timeout 30s # на команду целиком, включая входПоле timeoutMs в настройках ограничивает один ответ, а команда делает
несколько запросов подряд, так что общее время кратно ему. Если нужен предел на всё — это
--timeout, и он завершает команду кодом 9, закрыв соединение за собой.
Если строк нет вовсе, а команда всё равно не возвращается — это дефект: сообщите о нём, приложив
вывод --trace. Команда, которая напечатала ответ и не вышла, считается здесь поломкой.
«matches N chats»
"Иван" matches 2 chats — name one by its id:
123 Иван Петров
456 Иван и друзьяКод 2. Часть названия подошла к нескольким чатам, и программа отказывается угадывать: отправить
не в тот разговор нельзя отменить. Назовите точнее или используйте идентификатор из списка.
«no chat matches»
Код 6. Чат с таким именем не найден. Имена берутся из того, что вернул вход: личный чат
называется именем собеседника, и если контакт не известен, у чата может не быть названия вовсе —
тогда адресуйте его идентификатором из max chats list.
«profile … has sent N messages in the hour …»
Код 8. Сработал собственный лимит профиля в час — sendsPerHour, по умолчанию 30. В ошибке
сказано, когда можно отправить снова. Поднимайте лимит, только если действительно собирались
отправить столько: max config set sendsPerHour <n>.
«chat … is not on the recipient list of profile …»
Код 7. У профиля включён список получателей, и этого чата в нём нет. Если чат можно, добавьте
его сами: max <профиль> recipients add <чат>. Агент здесь должен остановиться и спросить вас
(security.md).
outcome_unknown после отправки
Код 14. Сообщение могло уйти. Это не ошибка и не успех: ответ не пришёл, а запрос ушёл.
Повторять можно только с тем же --send-id, который назван в сообщении об ошибке, — MAX схлопнет
дубликат:
max messages send 0 "текст" --send-id 1789784741828Никогда не повторяйте отправку без --send-id: это второе сообщение человеку.
«MAX answered with something we did not expect»
Строка на stderr, команда при этом работает. Ответ MAX разошёлся с тем, что записано в спецификации: протокол неофициальный и меняется без предупреждения.
Ничего не сломалось — но если после этого в выводе появились пустые поля, дело в этом. Сообщите, приложив строку целиком: в ней есть путь поля и ожидавшийся тип и нет содержимого.
Пустой список чатов
Сначала проверьте, что смотрите не в локальную копию:
max chats list --trace # видны ли запросы к MAX
max cache clear # забыть локальную копию и спросить зановоЕсли на первом запуске список был, а на втором подряд пуст — это дефект, сообщите о нём. Второй вход получает от MAX только то, что изменилось, а остальное полагается брать из локальной копии.
Ctrl-C
Код 130. Команда остановилась там, где была, и закрыла соединение. Если нажали во время
отправки, сообщение могло уйти: посмотрите чат (max messages list <чат> --limit 3), прежде чем
отправлять снова.
Ответ не «y» на вопрос перед изменением заканчивается так же: ничего не сделано.
«the message store was written by a newer version …»
Код 3. Другой CLI — локальная копия общая с tg — или более новый max обновил её так, что эта
версия её не прочитает. Запустите max upgrade. Из копии ничего не пропадает.
«nothing recorded for profile … yet — run the command once without --offline»
Код 6. --offline и messages search отвечают только из локальной копии, а этот профиль ещё
ничего в неё не прочитал. Сначала запустите одну команду с подключением, например
max chats list.
messages search ничего не находит
Поиск читает только то, что сохранено на этой машине, и никогда не спрашивает MAX. Пустой ответ
значит «не сохранено», а не «такого не писали». Прочитайте чат (max messages list <чат>) или
скачайте его историю max store fetch <чат> и поищите снова (archive.md).
«max serve is already running for profile …»
Код 2. Один serve на профиль. max server status скажет, какой процесс и с какого времени;
max server stop остановит запущенный через server start или службу.
Сервер в фоне не запускается
Причину покажет max server logs. У службы обычная причина — ключница: служба стартует раньше,
чем ключница открыта, или без XDG_RUNTIME_DIR. Если перенесли Node или max, снова выполните
max server install: служба запускает те пути, с которыми её поставили (archive.md).
npx @leemour/max-cli ставит не ту версию
npx кэширует. Явная версия обходит кэш:
npx @leemour/max-cli@latest --versionКак сообщить о проблеме
max doctor report # что попадёт в отчёт и чего в нём не будет
max doctor report create # записать отчёт в файл и показать, как его отправитьcreate пишет файл max-report-<время>.json в текущий каталог (права 0600). В нём версия, среда
и система, то же, что показывает max doctor, последний запуск, который кончился ошибкой, и
последние 20 действий-записей. Текстов сообщений, названий чатов, имён, номеров телефонов и токена в
нём нет. Номера чатов и сообщений заменены метками: внутри одного отчёта метка у чата одна и та же,
а в следующем отчёте — другая. Запуск, кончившийся ошибкой, сохраняется сам, даже без --record
(diagnostics.md). Про другой запуск — --run <id>, номера показывает
max runs list.
Дальше команда печатает ссылку на новую задачу в github.com/leemour/max-cli/issues: заголовок и заготовка текста уже заполнены. Нужен аккаунт на GitHub. Перетащите файл отчёта в поле текста, напишите, что делали и что случилось, и нажмите «Submit new issue».
Задачи на GitHub видны всем, и приложенный файл тоже.
⚠ Не прикладывайте содержимое ~/.cache/max-cli/ и ~/.local/share/cli-messaging/ — там лежат тексты сообщений.