Skip to content

Fix interactive UI creating duplicate messages on button press#67

Merged
six-ddc merged 1 commit into
six-ddc:mainfrom
zhou-zhichao:fix/interactive-ui-duplicate-messages
Apr 22, 2026
Merged

Fix interactive UI creating duplicate messages on button press#67
six-ddc merged 1 commit into
six-ddc:mainfrom
zhou-zhichao:fix/interactive-ui-duplicate-messages

Conversation

@zhou-zhichao

Copy link
Copy Markdown
Contributor

Summary

  • Handle BadRequest: Message is not modified specifically — keep existing message instead of creating a duplicate
  • Delete old message before sending new one when edit genuinely fails, ensuring at most one interactive UI message per topic

Problem

Each button press (Up/Down/Enter/Space/Tab) on interactive UI inline keyboards could create a new message instead of editing the existing one. This happened because handle_interactive_ui caught all exceptions from edit_message_text and fell through to send_message without deleting the old message.

The most common trigger: Telegram raises BadRequest: Message is not modified when terminal content hasn't changed after a button press — the broad except Exception treated this as a failure and sent a duplicate.

Changes

Only src/ccbot/handlers/interactive_ui.py:

  1. Import BadRequest from telegram.error
  2. Catch BadRequest with "Message is not modified" → return True (keep existing message)
  3. On other edit failures → delete_message the old one before sending new

Test plan

  • Press interactive UI buttons (Up/Down/Space/Enter) rapidly — should always have exactly one UI message
  • Delete the UI message externally in Telegram, then press a button — should send a fresh message (no error)
  • Verify AskUserQuestion, PermissionPrompt, ExitPlanMode all work correctly

Fixes #66

When editing an existing interactive message fails with "Message is not
modified" (content unchanged after button press), the old code caught all
exceptions and fell through to send a new message, causing duplicates.

Changes:
- Handle BadRequest "Message is not modified" specifically: keep existing
  message and return early instead of creating a duplicate
- On other edit failures, send the replacement message first, then delete
  the old one only after the new one succeeds — prevents stranding users
  without controls if the replacement send also fails

Fixes six-ddc#66
@zhou-zhichao zhou-zhichao force-pushed the fix/interactive-ui-duplicate-messages branch from 43448aa to 4106d55 Compare March 26, 2026 01:51
@six-ddc

six-ddc commented Apr 22, 2026

Copy link
Copy Markdown
Owner

Thanks @zhou-zhichao — excellent root-cause analysis. Distinguishing BadRequest: Message is not modified from real edit failures, and deleting the old message only after the replacement succeeds, is the right ordering. Much cleaner than the earlier attempts at this bug. Merging now. 🙏

@six-ddc six-ddc merged commit 865ab89 into six-ddc:main Apr 22, 2026
1 check failed
TejNote added a commit to TejNote/ccbot that referenced this pull request May 8, 2026
상단에 fork notice 추가하여 TejNote/ccbot이 six-ddc/ccbot 의 fork임을 명확히
표시. Features 섹션을 'Upstream' / 'Fork additions' 두 그룹으로 분리해
어떤 기능이 fork 추가분인지 한눈에 보이도록 정리.

Codex/OMX provider 라우팅, plugin skill menu (`/favorite`+사용 빈도 sorting),
MessageBatcher, DirectMessage 큐, `ccbot send` CLI subcommand, status msg ID
영속화, parse_status_line의 background-shell spinner 차단 등 fork 추가 기능을
Fork additions 절에 항목별로 설명. 옵션 env 변수 표에도 🔱 마크로 fork-only
설정(`CCBOT_BATCH_WINDOW`, `CCBOT_SHOW_USER_MESSAGES`,
`CCBOT_SHOW_TOOL_CALLS`)을 표시.

File Structure 트리에 send.py / skill_registry.py / message_batcher.py 등
신규 파일과 수정된 모듈을 🔱 표시와 함께 명시.

Changelog (fork) 섹션 신설 — 머지된 PR(#1, #2, #4, #5)과 주요 commit을 시간
역순으로 정리하고, 아직 fork에 반영 안 된 upstream 커밋 3건(six-ddc#67, six-ddc#73,
f5ddd7f)을 'Pending upstream merges' 표로 트래킹.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Time4Mind referenced this pull request in Time4Mind/ccbot May 9, 2026
When editing an existing interactive message fails with "Message is not
modified" (content unchanged after button press), the old code caught all
exceptions and fell through to send a new message, causing duplicates.

Changes:
- Handle BadRequest "Message is not modified" specifically: keep existing
  message and return early instead of creating a duplicate
- On other edit failures, send the replacement message first, then delete
  the old one only after the new one succeeds — prevents stranding users
  without controls if the replacement send also fails

Fixes six-ddc#66
TejNote added a commit to TejNote/ccbot that referenced this pull request May 14, 2026
upstream six-ddc/ccbot의 pending merge 3건(six-ddc#67, six-ddc#73, f5ddd7f)을 cherry-pick + 영향 받는 fork-only 테스트 1건 시그니처 갱신. pyproject.toml 1.0.0→1.0.1, CHANGELOG.md [1.0.1] 섹션 추가. 283/283 통과.
HParis added a commit to HParis/ccbot that referenced this pull request Jun 9, 2026
Cherry-picks the still-relevant upstream/main fixes, adapted to the iTerm2
backend and covered by tests:

- six-ddc#88 (7c2e15c): wrap the cosmetic pre-injection Telegram calls — send_action,
  enqueue_status_update, and the interactive-UI precheck — in try/except across
  text/photo/voice/forward handlers, so a transient TimedOut on a flaky link can
  no longer abort the handler before send_to_window and silently drop the user's
  message (the update offset has already advanced, so Telegram won't redeliver).
- six-ddc#67 (865ab89): on a hard interactive-UI edit failure, keep the old message and
  delete it only AFTER the replacement send succeeds, so a failed replacement
  never strands the user without controls. ("Message is not modified" was already
  handled on this branch.)
- Write line count (f5ddd7f): compute from the tool_use input content, not the
  result confirmation string, so it stops always showing "Wrote 1 lines".

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

Interactive UI creates duplicate messages on button press instead of editing in-place

2 participants