Свежее открытие: как 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, и их стоит выставить руками.
Самое неприятное в этой истории — что сломалось не самое сложное место. Спек-файлы, подсчёты, раздача задач между агентами — всё это работало. Уронил систему отсутствующий файл конфига, которого никто осознанно не пропускал.
Так что если меня в ближайшее время спросят про свежее открытие, ответ будет такой: когда ИИ настраивает окружение за вас, он настраивает его по умолчанию. А «по умолчанию» и «безопасно для ночного прогона» — это разные вещи.