# 콜드메일 워크플로우 interrupt() 상태 보존 문제 해결 **날짜**: 2026-01-21 **작성자**: happybell80 **관련 파일**: `rb8001/app/services/workflows/coldmail_workflow.py`, `rb8001/app/services/slack/coldmail_service.py` --- ## 문제 상황 - Slack 버튼 클릭 시 `Email not found in waiting_confirmation` 에러 발생 - `interrupt()` 호출 후에도 워크플로우가 계속 진행되어 `waiting_confirmation`이 비워진 상태로 저장됨 ## 원인 분석 - LangGraph 1.0의 `interrupt()`는 노드 실행을 즉시 중단시킴 - 노드가 반환(return)되기 전에 `interrupt()`가 호출되면 해당 노드 내 상태 변경이 checkpoint에 저장되지 않음 - 재개 시 노드가 처음부터 다시 실행됨 ## 해결 방안 노드 분리 설계 적용: - `coldmail_workflow.py:115-160`: `process_node` - 상태 업데이트 후 반환 (waiting_confirmation 저장) - `coldmail_workflow.py:163-197`: `wait_confirmation_node` - interrupt() 호출하여 사용자 확인 대기 - `coldmail_workflow.py:200-236`: `confirm_node` - 재개 후 confirmed_email_id 처리 워크플로우 플로우: `fetch → filter → process → wait_confirmation (interrupt) → confirm → send → END` ## 테스트 결과 - `tests/test_coldmail_interrupt_return_pattern.py`: 4개 테스트 모두 통과 - 기존 `tests/test_coldmail_workflow_interrupt.py`: 4개 테스트 모두 통과 ## 교훈 1. **LangGraph interrupt 동작 이해**: `interrupt()` 호출 시 노드 반환 전이면 상태가 저장되지 않음 2. **노드 분리 필수**: 상태 저장이 필요한 로직과 `interrupt()` 호출을 별도 노드로 분리 3. **TDD 중요성**: 단위 테스트로 interrupt/resume 동작 검증 후 배포