Ошибки и failure modes
Общий формат
Пользовательские ошибки CLI выводятся в stderr в формате:
error: <message>Команда завершается с ненулевым exit code.
Частые блокирующие ситуации
| Ситуация | Что означает | Что сделать |
|---|---|---|
Неотслеживаемый файл конфликтует с remote при sync | файл в skills/, mcp/ или loadouts/ совпадает по имени с файлом из remote | переименовать файл, опубликовать через aiman push или использовать --force (файл будет удалён) |
Remote новее при push | опубликованное состояние ушло вперёд | выполнить aiman sync |
| История Git разошлась | AIM не может безопасно выбрать состояние | восстановить Git вручную |
| AI-среда не найдена | адаптер не нашёл base dir | указать путь в aim.local.yaml |
| MCP env не задана | required переменная отсутствует | ввести при sync или добавить в aim.local.yaml |
| Невалидный Skill | нет frontmatter, нет name, нет description или пустое тело | исправить skills/<name>.md |
| Невалидный MCP Item | нет обязательного поля или YAML невалиден | исправить mcp/<name>.yaml |
Нет активного репозитория при import (точечном или без имени) | репозиторий инвентаря не выбран | выполнить aiman init <url> или aiman switch <path> |
Недопустимое имя элемента при import | аргумент <name> пустой, содержит /, \, .., управляющие символы или длиннее 255 символов | передать имя элемента, а не путь к файлу; файл добавляется через aiman add |
MCP-сервер с неподдерживаемым транспортом при import mcp | сервер объявлен как http/sse или через url, а не через command | AIM управляет только stdio-серверами; оставить такой сервер настроенным в среде вручную |
Неизвестная среда в --from при aiman import | значение --from не входит в claude-code, cursor, codex | исправить значение флага; список доступных — в тексте ошибки |
Опечатка в имени подкоманды import | aiman import skil ... — skil не распознан как skill/mcp | проверить написание подкоманды; aiman import без аргументов — это отдельный режим discovery, а не опечаточный skill/mcp |
Loadout не найден при apply --loadout | в loadouts/ нет файла или поля name с таким именем | проверить имя; список доступных — в hint |
| Невалидный loadout | нет name, пустой items, неверный префикс ссылки или YAML невалиден | исправить loadouts/<name>.yaml |
Сломанная ссылка loadout при push | skill:<name> или mcp:<name> не существует в инвентаре | исправить items или добавить элемент в инвентарь |
Пин указывает на несуществующий loadout при sync | loadout, закреплённый через apply --pin, удалён, переименован или отсутствует в текущем репозитории | aiman apply --default или aiman apply --unpin, чтобы снять пин, либо восстановить/переименовать loadout обратно |
Конфликт флагов apply (--pin/--default/--unpin) | несовместимая комбинация флагов пина | использовать флаги по отдельности — см. Справочник CLI |
| Нет доступа к remote | Git не может прочитать или записать репозиторий | проверить сеть, credentials и права |
Ошибки импорта
Все три ошибки ниже возникают до записи на диск: инвентарь и AI-среды остаются нетронутыми.
Нет активного репозитория инвентаря — aiman import skill и aiman import mcp не пишут в текущую директорию:
error: no active inventory repository; run 'aiman init' firstПодключите репозиторий (aiman init <url>) или переключитесь на существующий (aiman switch <path>). Проверка выполняется и с флагом --print.
Недопустимое имя элемента — имя проверяется до построения пути записи, поэтому импорт нельзя увести за пределы репозитория инвентаря:
error: invalid item name "../evil": must not contain "/" or "\"Отклоняются пустое имя, ., .., имена с / или \, абсолютные пути, управляющие символы и имена длиннее 255 символов. Аргумент команды — это имя элемента в AI-среде, а не путь к файлу.
MCP-сервер использует неподдерживаемый транспорт — импортировать можно только stdio-серверы (те, у которых задан command):
error: MCP server "remote-tool": unsupported transport "http" (only stdio servers can be imported)Такой сервер не создаётся в инвентаре пустой заготовкой: команда останавливается и называет причину. Остальные серверы того же конфига импортируются как обычно.
Discovery (aiman import без имени): ошибки и состояния плана
Два настоящих failure mode — до любого обращения к диску:
Неизвестная среда в --from:
Error: unknown environment: bogus; available: claude-code, cursor, codexОпечатка в имени подкоманды — родительская команда объявлена с Args: cobra.NoArgs, поэтому нераспознанный первый аргумент не проваливается молча в discovery:
Error: unknown command "skil" for "aiman import"Отсутствие активного репозитория — та же ошибка и то же требование, что и у точечных import skill/import mcp (см. выше), действует во всех режимах (--dry-run, --yes, без флагов).
Остальное ниже — не ошибки команды: exit code остаётся нулевым, discovery успешно построила план, а следующие состояния — это то, что в нём показано, и не блокируют весь план, только конкретный элемент.
Неполный скан. Если чтение или разбор одного источника не удалось (например, невалидный mcp.json), это не прерывает всю команду — план строится по остальным источникам, а в stderr печатается предупреждение:
warning: scan was incomplete — see per-source errors aboveaiman import --yes при неполном скане отказывается писать что-либо вообще, пока источник не будет исправлен или исключён через --from.
Source conflict. Один и тот же ключ (<kind>:<name>) найден с разным содержимым в разных средах — ничего не выбирается по порядку обхода, элемент попадает в категорию conflicts плана:
conflicts: 1
mcp:jira — found with different command/args/env across sourcesУ скилла отдельно выделяется policy conflict — тот же payload, но разные явные targets в frontmatter:
skill:review-code — same skill content but different explicit targets across sourcesInventory conflict. Payload кандидата отличается от уже существующего элемента инвентаря с тем же именем, либо в инвентаре одновременно есть skills/<name>.md и skills/<name>/SKILL.md:
skill:review-code — differs from the existing inventory item with the same nameLocal-value conflict. Несколько источников расходятся в значении одной и той же MCP env-переменной — значение не заполняется автоматически на --yes, даже если сам payload элемента однозначен:
mcp:jira (local MCP value conflict: TOKEN — not auto-filled)Unsupported transport — та же причина, что и у точечного aiman import mcp выше, показывается в плане отдельной категорией unsupported, а не как error:
unsupported: 1
mcp:docs-site — unsupported transport "http" (only stdio servers can be imported)Ни в одном из перечисленных сообщений — ни в плане, ни в предупреждениях, ни в --dry-run — не может оказаться реального значения MCP env-переменной: discovery либо не может его прочитать в принципе, либо не может определить, какое из нескольких значений верное.
Ошибки loadout
Loadout не найден (aiman apply --loadout):
hint: available loadouts: dev, docs
error: loadout "ghost" not found in loadouts/Строка hint печатается, когда валидных loadout от одного до пяти, и перечисляет значения поля name, а не имена файлов. Отсутствующая или пустая директория loadouts/ даёт ту же ошибку not found, но без подсказки.
Loadout невалиден — apply --loadout останавливается на первой ошибке:
error: loadout "empty": items: cannot be emptyaiman push выводит все ошибки формата по всем файлам loadouts/ сразу (с полным путём к файлу):
error: /home/user/aim-inventory/loadouts/empty.yaml: items: cannot be emptyСломанная ссылка на элемент инвентаря (aiman push, блокирует публикацию):
error: loadout "Documentation Work" references unknown skill "missing-skill"
hint: check loadouts/documentation-work.yaml → itemsЛюбую неуспешную валидацию push завершает общей строкой error: validation failed — fix errors before publishing.
Та же ситуация при apply --loadout — предупреждение, а не ошибка: элемент пропускается, применение продолжается:
warning: loadout "dev": no valid inventory item for skill:ghost (skipped)Предупреждения loadout, не блокирующие ни push, ни apply: отсутствие description и несовпадение имени файла с нормализованным name.
Пин loadout
Пин указывает на loadout, которого больше нет — aiman sync останавливается, не тронув AI-среды и не обновив synced_hash:
error: pinned loadout "documentation-work" not found in inventoryЭта ошибка отличается от loadout "X" not found in loadouts/, которую выдаёт apply --loadout без пина — тексты различаются намеренно, чтобы источник ошибки было легко отличить в логах. Причины: loadout переименовали или удалили, репозиторий опубликовал более новое состояние с другой машины, либо aiman switch переключил на репозиторий, где такого loadout никогда не было. Чтобы восстановиться:
- снять пин без применения чего-либо:
aiman apply --unpin; - или вернуться к полному инвентарю:
aiman apply --default; - или восстановить/переименовать loadout под ожидаемым именем в репозитории инвентаря и повторить
aiman sync.
Конфликты флагов apply --pin / --default / --unpin — проверяются до чтения инвентаря, до диспетчеризации в apply:
| Комбинация | Ошибка |
|---|---|
--pin без --loadout | error: --pin requires --loadout <name> |
--default + --loadout | error: --default and --loadout are mutually exclusive |
--default + --pin | error: --pin is redundant with --default |
--unpin вместе с --loadout, --pin или --default | error: --unpin does not apply — combine only alone |
Полное описание флагов — в Справочнике CLI, поле конфига — в Справочнике конфигурации.
--dry-run
Для опасных операций сначала используйте dry-run:
aiman push --dry-run
aiman sync --dry-run
aiman apply --dry-run
aiman apply --loadout <name> --dry-runDry-run показывает план без записи в Git, репозиторий инвентаря или AI-среды. Для apply --loadout dry-run обязателен к привычке: строки D в плане показывают, что будет удалено из сред.
--force
aiman sync --force разрешает потерю локальных изменений при применении опубликованного состояния.
Используйте этот флаг только если локальное рабочее дерево можно восстановить или потерять.