← Назад в блог

Свежее открытие: как vitest по умолчанию съел 32 ГБ и уронил оркестратор

На собеседованиях иногда спрашивают: «Какое у вас было последнее открытие?» Вопрос хороший, потому что проверяет не знания, а привычку разбираться до конца. Вот моё свежее — ему меньше суток.

Ночной прогон, который не прогнался

Вчера вечером я поставил на ночь своего оркестратора. Схема простая: есть набор спек-файлов с подсчётами, оркестратор раздаёт их субагентам, те делают задачу, прогоняют проверки, отчитываются. Моих решений в цепочке не предусмотрено — всё должно было крутиться само.

Утром прихожу: задача не выполнена. Не «выполнена плохо», а просто остановилась где-то посередине. Терминал, в котором всё это жило, закрыт.

Первая гипотеза была неправильной

Первым делом я подумал на окружение. Запускал я всё в терминале, поэтому поставил совершенно другую IDE, открыл в ней ту же сессию через resume и написал одно слово: «Продолжай».

Новая IDE вылетела тоже. Вместе с запущенным внутри плагином. Это был полезный результат: значит, дело не в терминале и не в конкретном клиенте. Что-то в самой задаче роняет процесс.

Разбираемся вместе с кодом

Дальше мы с Claude Code разбирали проблему уже вдвоём, по логам и по тому, что успело остаться на диске. Причина оказалась банальной до обидного.

Один из субагентов-исполнителей перед своей задачей запускал тесты фронтенда: bun run vitest. Сам vitest в проекте появился не из моих рук — его в какой-то момент добавил код, когда ему понадобились проверки. Добавил пакет, добавил скрипт в package.json. А vitest.config не написал вообще: ни лимита воркеров, ни таймаутов, ни ограничения на параллельность файлов.

Дефолт vitest — гонять все тестовые файлы параллельно, по воркеру на каждое ядро. Каждый воркер поднимал свой jsdom, свой набор моков и свои фикстуры с данными для подсчётов. В сумме они разобрали все 32 ГБ свободной памяти. В этот момент агент пытался запустить что-то своё поверх тестов — памяти не осталось, и система убила самый жирный процесс. Им оказался процесс IDE целиком, вместе с терминалом и всей сессией.

То есть оркестратор ничего не «решал неправильно». Он честно делал то, что просили, а под ним просто выдернули пол.

Что я из этого вынес

Не доверяйте конфигурированию целиком. Агент отлично добавляет инструменты, но добавляет их в дефолтной конфигурации. А дефолты инструментов рассчитаны на человека за ноутбуком, который видит, что машина начала свопить, и жмёт Ctrl+C. Ночью за ноутбуком никого нет.

Практически это означает две вещи:

  • В инструкциях агенту явно прописывать ограничения окружения. Не «запусти тесты», а «запусти тесты не больше чем в N воркеров, с таймаутом, и не параллельно с другими тяжёлыми процессами». Ресурсы машины — часть спецификации, а не фон.
  • Любой инструмент, который агент завёл сам, проверять на конфигурацию, а не только на наличие. vitest.config.ts, pytest.ini, jest.config — если файла нет, значит работают дефолты, и надо понимать, какие именно. Для vitest это maxWorkers, fileParallelism и testTimeout, и их стоит выставить руками.

Самое неприятное в этой истории — что сломалось не самое сложное место. Спек-файлы, подсчёты, раздача задач между агентами — всё это работало. Уронил систему отсутствующий файл конфига, которого никто осознанно не пропускал.

Так что если меня в ближайшее время спросят про свежее открытие, ответ будет такой: когда ИИ настраивает окружение за вас, он настраивает его по умолчанию. А «по умолчанию» и «безопасно для ночного прогона» — это разные вещи.

Эта статья создана в гибридном формате человек + ИИ. Я задаю направление и тезисы, ИИ помогает с текстом, я редактирую и проверяю. Ответственность за содержание — моя.

← Назад в блог