Skip to content

feat: warn once when rendered callback_data exceeds 64 bytes - #60

Open
Dramex wants to merge 1 commit into
grammyjs:mainfrom
Dramex:feat/warn-on-long-callback-data
Open

Dramex wants to merge 1 commit into
grammyjs:mainfrom
Dramex:feat/warn-on-long-callback-data

Conversation

@Dramex

@Dramex Dramex commented Apr 17, 2026

Copy link
Copy Markdown
Contributor

Closes #46.

Telegram rejects `callback_data` longer than 64 bytes with `BUTTON_DATA_INVALID`, and the menu plugin adds the menu id plus a 5-byte hash/fingerprint suffix to every button's `callback_data`. That combination makes it surprisingly easy for a long menu id + a long payload to cross the limit — and the Telegram error does not identify which button is at fault. Reporters on #46 described spending multiple hours debugging this.

This PR adds a one-time `console.warn` on the first render where any rendered `callback_data` exceeds 64 bytes. The warning includes the menu id, the row/column of the offending button, the actual byte length, and the approximate usable payload size (`~58 - id.length` bytes). Subsequent renders of the same menu instance stay silent so the console is not flooded.

Per the maintainer's direction in the issue thread, this is a warning, not a validation — the plugin does not throw, and will not become brittle if Telegram ever raises the limit.

Test plan

  • `deno fmt --check` clean
  • `deno lint` clean
  • `deno check --allow-import src/mod.ts` clean

Manual verification: construct a `Menu('x'.repeat(60))` with a `.text({ text: 'hi', payload: 'y'.repeat(20) }, handler)` and render it via `render(ctx)` — the warning fires exactly once.

Telegram rejects callback_data longer than 64 bytes with
`BUTTON_DATA_INVALID`. The menu plugin adds the menu id plus a 5-byte
hash/fingerprint suffix to every `callback_data`, so it is surprisingly
easy for a long menu id + a long payload to cross the limit — and the
resulting error from Telegram does not reveal which button is at fault.

Check each rendered `callback_data` and emit a one-time `console.warn`
on the first render that exceeds 64 bytes, naming the menu id, the
row/column of the offending button, the actual byte length, and the
approximate usable payload size. The warning fires once per menu
instance to avoid flooding the console on repeated renders.

Per grammyjs#46, this is a warning rather than a hard validation so the plugin
does not become brittle if Telegram ever raises the limit.

Closes grammyjs#46.

@KnorpelSenf KnorpelSenf left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you remove the LLM artefacts from the changelog? I don't like to have non-ASCII127 characters in my source files

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.

feat: check payload data length and throw exception when it exceeds limit

2 participants