Решение проблем
Это руководство помогает восстановиться после типичных проблем при работе с MCP Moira workflows.
Восстановление контекста после архивации
Когда беседа архивируется или компактируется, агент теряет:
- Текущий execution ID (processId)
- Контекст шага workflow
- Информацию о прогрессе
Состояние workflow сохраняется на MCP сервере - теряется только память агента.
Шаги восстановления
- Найти активные executions:
session({ action: "executions" })Возвращает список executions со статусом, workflow ID и заметками:
[ { "executionId": "abc-123", "workflowId": "development-flow", "status": "waiting", "note": "Фича: система авторизации", "currentNodeId": "implement-step" }]- Получить текущий шаг без продвижения:
session({ action: "current_step", executionId: "abc-123" })Возвращает текущую директиву и контекст:
{ "attemptId": "attempt-current", "directive": "Реализовать фичу...", "completionCondition": "Фича работает и протестирована", "inputSchema": { ... }}- Продолжить workflow:
step({ processId: "abc-123", attemptId: "attempt-current", input: { ... } })Сохранение Process ID
Для облегчения восстановления сохраняйте process ID в рабочей директории:
# Создать process-id.txt в директории фичиecho "abc-123" > ./feature-name/process-id.txtВключайте в архивы сессий:
- Название фичи
- Process ID
- Описание текущего шага
Справочник инструментов навигации
session - executions
Список всех активных workflow executions текущего пользователя.
Вызов: session({ action: "executions" })
Фильтры:
status: Массив статусов -["waiting", "running", "completed", "failed"]workflowId: Фильтр по конкретному workflowsearch: Поиск в заметках executions
Пример с фильтрами:
session({ action: "executions", status: ["waiting", "running"], search: "auth"})session - current_step
Получает текущую директиву шага без продвижения workflow.
Вызов: session({ action: "current_step", executionId: "..." })
Параметры:
executionId(обязательно): ID execution для проверки
Возвращает:
attemptId: Идентификатор для отправки именно этого текущего предъявленияdirective: Что делатьcompletionCondition: Критерии успехаinputSchema: Структура ответа
session - execution_context
Получает полное состояние execution включая переменные контекста.
Вызов: session({ action: "execution_context", executionId: "..." })
Параметры:
executionId(обязательно): ID execution для просмотра
Возвращает:
executionId: UUID executionworkflowId: Выполняемый workflowstatus: Статус execution (running, waiting, completed, failed)currentNodeId: ID текущего узлаwaitingForInputNodeId: Узел ожидающий input (если есть)note: Заметка executioncontext.variables: Переменные контекстаcontext.nodeStates: Состояния узловcreatedAt,updatedAt,completedAt: Временные меткиerror: Сообщение об ошибке (если failed)
Типичные проблемы
“Process not found or expired”
Причина: Неверный или истёкший processId
Решение:
- Используйте
session({ action: "executions" })для поиска активных executions - Используйте правильный executionId из списка
- Process ID - это UUID типа
abc123-def456-...
“Execution is not waiting for input”
Причина: Попытка продвинуть завершённый или упавший execution
Решение:
- Проверьте статус execution через
session({ action: "execution_context", executionId: "..." }) - Статус должен быть
waitingдля принятия input - Если
completedилиfailed, запустите новый execution
Ошибки валидации на step()
Причина: Input не соответствует inputSchema
Решение:
- Проверьте
inputSchemaтекущего шага - Убедитесь что имена полей совпадают точно (регистрозависимо)
- Убедитесь что типы данных совпадают (string vs number)
- Включите все обязательные поля
ATTEMPT_PROCESSING
Причина: Другой вызывающий всё ещё владеет активной заявкой на изменение именно этого шага.
Решение: Повторите вызов с теми же Process ID, идентификатором попытки и входными данными. Не заменяйте попытку и не изменяйте ввод.
ATTEMPT_STALE
Причина: Попытка больше не соответствует текущему предъявлению execution и была отклонена до работы обработчика.
Решение: Автоматически вызовите session({ action: "current_step", executionId: "..." }), затем
один раз повторите исходную отправку с возвращённым идентификатором попытки. Не используйте
устаревший идентификатор повторно.
ATTEMPT_CONFLICT
Причина: Попытка уже связана с другими входными данными, поэтому новая отправка отклонена до работы обработчика.
Решение: Автоматически вызовите session({ action: "current_step", executionId: "..." }),
отбросьте конфликтующую попытку и продолжите по возвращённой директиве и входной схеме. Не
повторяйте отклонённый ввод для текущего предъявления.
ATTEMPT_INVALID_OR_EXPIRED для шага
Причина: Попытка шага недоступна и отклонена до работы обработчика. Это восстановление
применимо, только если ошибка явно предписывает прочитать current_step: у недоступной попытки
запуска нет текущего шага для восстановления.
Решение: Автоматически вызовите session({ action: "current_step", executionId: "..." }),
отбросьте недоступную попытку и продолжите по возвращённой директиве и входной схеме.
ATTEMPT_OUTCOME_UNKNOWN
Причина: Moira не может доказать, завершилось ли уже принятое изменение и связанный с ним возможный внешний эффект.
Решение: Изучите выполнение через session({ action: "current_step", executionId: "..." }) и
состояние соответствующей внешней системы. Не повторяйте изменение автоматически.
CURRENT_PRESENTATION_STALE
Причина: Сохранённая живая попытка относится к другой ноде или к поверхности продолжения, которой в текущем определении больше нет: изменилось что-то из того, что приостановленная нода объявляет о своей работе, либо изменилась запись реестра для объявленной ею на вход глобальной переменной. Безопасно перепривязать такую попытку к текущему execution нельзя. Изменение, не затрагивающее эту поверхность, к этому состоянию не приводит: смена версии или тегов, правка другой ноды и косметическое изменение самой приостановленной ноды пригодность сохраняют.
Решение: Не повторяйте старую попытку. Вызовите
session({ action: 'diagnose', executionId: '...' }): он назовёт, какие факты приостановленного
шага изменились, сохранилась ли его нода и что ещё стоит между выполнением и следующим шагом. Затем
восстановите выполнение вызовом
session({ action: 'recover', executionId: '...', nodeId: '<нода для возобновления>', variableValues: { ... } }):
он предъявит названную вами ноду заново вместе со значениями, которые нужны этому шагу, и вернёт
свежий идентификатор попытки шага для продолжения. Называйте ноду, на которой выполнение может
ожидать: agent-directive, teleport, materialize, lock или subgraph. Любая другая нода отклоняется,
потому что возобновление на ней означало бы прогон workflow вперёд, а не восстановление.
Выполнение останавливается на названной ноде и дальше не идёт, но нода lock при появлении
выполнения создаёт блокировку и отправляет код подтверждения, а нода subgraph заходит в дочернее
выполнение: выбирайте такую цель, только если этот эффект вам нужен.
Восстановление отклоняется и тогда, когда выполнение и так может продолжиться, и для выполнения,
которое уже завершено или отменено, — таким оно и останется; отказ ничего не меняет.
Агент забывает контекст Workflow
Причина: Сессия была архивирована/компактирована
Решение:
- Проверьте process-id.txt в рабочей директории
- Используйте
session({ action: "current_step" })для получения контекста - Напомните агенту: “Продолжай workflow {processId}”
[[UNDEFINED_VARIABLE]] в директиве в рантайме
Причина: Используемая переменная не была разрешена при отрисовке директивы. Три причины:
- Переменная не объявлена в
variableRegistry. - Переменная объявлена, но без
default, и её не записал вышестоящий узел до того, как директива её использовала. - Голый
{{...}}был помещён в данные, которые агент вернул черезstep(), и эти данные позже подставились в директиву (template-in-data). Возвращаемые значения данных литеральны — они не пересканируются как шаблоны.
Движок логирует предупреждение с указанием оставшегося плейсхолдера и executionId.
Решение:
- Объявите переменную в
variableRegistryсо значениемdefault. - Убедитесь, что вышестоящий узел записывает переменную (через
globalInputs) до её первого использования. - Никогда не подставляйте
{{...}}в данные, возвращаемые изstep()— держите шаблоны только в статических полях узла.
Сценарии восстановления
Сценарий: Возобновление после прерывания
Пользователь: Продолжай работу над фичей авторизации
Агент:1. session({ action: "executions", search: "auth" }) → Найден: executionId: "abc-123", status: "waiting"
2. session({ action: "current_step", executionId: "abc-123" }) → attemptId: "attempt-current", directive: "Реализовать endpoint логина"
3. [Выполняет работу]
4. step({ processId: "abc-123", attemptId: "attempt-current", input: { result: "done" } })Сценарий: Найти потерянный Process ID
Пользователь: Какие workflows я запустил?
Агент:1. session({ action: "executions" }) → Список всех активных executions с заметками
2. session({ action: "execution_context", executionId: "abc-123" }) → Показывает полный контекст включая переменныеСценарий: Проверить почему Workflow застрял
Агент:1. session({ action: "execution_context", executionId: "abc-123" }) → status: "waiting", currentNodeId: "validation-step"
2. session({ action: "current_step", executionId: "abc-123" }) → Показывает чего ожидает workflowСвязанная документация
- Руководство для агентов - Основы использования tools
- Справочник MCP Tools - Полная документация tools