**Root cause:** The `switch` statement was missing a `default` case. When `typ.type` didn't match any handled case, the loop continued forever because `curr` was never updated.
**Changes made:**
1. **`vibe-kanban/frontend/src/utils/executor.ts`** (line 59-60): Added `default:` to fall through with `ScriptRequest`, advancing to the next action for any unhandled types.
2. **`vibe-kanban/frontend/src/components/tasks/TaskFollowUpSection.tsx`**:
- Removed duplicate local `extractProfile` function (17 lines)
- Added import from `@/utils/executor`
- Updated usage to `extractProfileFromAction`
3. **`vibe-kanban/frontend/src/components/NormalizedConversation/RetryEditorInline.tsx`**:
- Removed duplicate local `extractProfile` function (17 lines)
- Added import from `@/utils/executor`
- Updated usage to `extractProfileFromAction`
Both type checks (TypeScript and Rust/cargo) pass successfully.