Repository navigation
fix(messages): only delete messages that belong to the given chat - #320
Merged
Merged
Conversation
In private chats and basic groups Telegram numbers messages with one account-wide counter, so messages.deleteMessages takes bare IDs and deletes the message from whichever chat holds it, for both sides. delete_message and delete_messages_bulk passed chat_id only to pick the method, so a wrong or injected ID deleted messages in another chat, including one outside TELEGRAM_ALLOWED_CHAT_IDS. Telethon documents that delete_messages does not check that the IDs belong to the chat. Both tools now look the IDs up in the chat first (get_messages(entity, ids=...) returns None for an ID from another chat) and delete nothing when any ID is not there. Channel deletes are already scoped by Telegram and skip the lookup. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_018Xun6C4mXUAKbVSmiEEh79
This was referenced Oct 17, 2026
AO review approved with one optional coverage note: the channel short-circuit was only exercised via delete_messages_bulk. Add the one-case test for the single-message tool. Co-Authored-By: Claude Code <[email protected]>
chigwell
approved these changes
Oct 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related to #317 — this hardens the server against the class of cross-chat deletion described there. Whether that incident was caused by this server has not been established; see the discussion in the issue.
What this changes
delete_messageanddelete_messages_bulknow verify that every ID they are askedto delete actually belongs to
chat_idbefore calling Telegram. If any ID is amessage of another chat, nothing is deleted and the tool reports which IDs are
foreign. Channel/supergroup deletes are skipped by the check — Telegram scopes
those by channel already.
Why the old behavior was hazardous for private chats
Private chats and basic groups share one account-wide message counter. For them
Telethon sends
messages.deleteMessageswith bare IDs (and Telethon's defaultrevoke=True), so a delete meant for chat A with a stale or shifted ID removes themessage that currently holds that ID in chat B — for both sides. A single tool
call with wrong IDs can wipe outgoing messages across several unrelated private
chats — the class of loss described in #317, though the cause of that incident has
not been established.
Telethon.get_messages(entity, ids=...)returnsNonefor an ID that does notbelong to that chat, so the check is one extra read before any delete — no extra
API surface, no behavior change for correct calls.
Tests
tests/test_delete_messages.pyruns the real Telethon request path against afake in-memory account where private chats share the counter:
delete_messagerefuses a message belonging to another chat and issues noDeleteMessagesRequest.delete_messagestill deletes a message that does belong to the chat.delete_messages_bulkrefuses atomically when any ID is foreign.delete_messages_bulkdeletes a valid set.and the bulk tool (Telegram scopes channel deletes itself).
Scope note
This PR removes the only plausible server-side path for cross-chat deletions, but it cannot confirm whether the server caused #317 — the reporter's Codex logs did not show delete calls either.
🤖 Generated with Claude Code