Skip to content

fix: prevent duplicate interactive UI messages#1

Merged
LikunYDev merged 1 commit intomainfrom
fix/duplicate-interactive-ui
Apr 2, 2026
Merged

fix: prevent duplicate interactive UI messages#1
LikunYDev merged 1 commit intomainfrom
fix/duplicate-interactive-ui

Conversation

@LikunYDev
Copy link
Copy Markdown
Owner

Summary

  • Fix AskUserQuestion/ExitPlanMode prompts appearing twice in Telegram
  • Remove fallback sender in status polling that raced with the JSONL path
  • Add retry loop in JSONL path for slow UI rendering

Problem

Two independent code paths could send the same interactive UI to Telegram:

  1. JSONL path (bot.py:handle_new_message): detects tool_use in JSONL, calls handle_interactive_ui()
  2. Status poll path (status_polling.py): detects UI in terminal pane, calls handle_interactive_ui() as a "fallback"

The fallback's get_interactive_msg_id() guard failed due to an async race — both paths called send_message() before either stored the message ID.

Log evidence:

04:08:45.510 - Set interactive mode (JSONL path)
04:08:45.533 - Set interactive mode (status poll)
04:08:45.544 - Sending interactive UI  ← PATH 1
04:08:45.866 - Sending interactive UI  ← PATH 2 (duplicate)

Fix

Single-sender design: only the JSONL path sends AskUserQuestion/ExitPlanMode UIs. The status poll's role is limited to set_interactive_mode() (suppressing status updates while the prompt is active).

The fallback was originally added because the JSONL path's 0.3s sleep sometimes wasn't enough for Claude Code to render the UI. Instead of a second sender, the JSONL path now retries with increasing delays (0.3s, 0.7s, 1.0s).

Changes

  • status_polling.py: remove get_interactive_msg_id fallback call for JSONL-tracked UIs
  • bot.py: replace single 0.3s sleep with retry loop (0.3s, 0.7s, 1.0s)

Test plan

  • Trigger AskUserQuestion from Claude Code — verify single UI message in Telegram
  • Trigger ExitPlanMode — verify single UI message
  • Trigger PermissionPrompt — verify it still works (sent by status poll path, unchanged)
  • Slow render scenario: verify retry loop catches UI on 2nd/3rd attempt

🤖 Generated with Claude Code

Remove the fallback sender in status_polling that raced with the JSONL
path, causing the interactive UI to be sent twice. Instead, make the
JSONL path (the sole sender) retry pane capture with increasing delays
(0.3s, 0.7s, 1.0s) to handle slow UI rendering.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@LikunYDev LikunYDev merged commit c5aef0b into main Apr 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant