start() put ephemeral into send_kwargs unconditionally, so the raw Messageable.send() path raised TypeError (discord.py's channel send has no ephemeral param). ephemeral is now passed only on the interaction-response paths (followup.send / response.send_message), which support it; raw-channel send never receives it.
Signed-off-by: disqualifier <dev@disqualifier.me>
delete_message_after was stored but never read and no on_timeout override existed, so the documented 'delete the message on timeout' never happened. added on_timeout that deletes self.message when the flag is set, swallowing only the expected discord.NotFound (already deleted) / discord.Forbidden (no permission) and letting any unexpected error surface.
Signed-off-by: disqualifier <dev@disqualifier.me>
get_page() out-of-range/negative wrap reset to page 0 but returned pages[0] (a single item) even with per_page>1, mis-shaping the page downstream; it now reroutes through get_page(0) so the normal slice logic applies. cache shorter than max_pages now raises ValueError at construction instead of an IndexError when the cache button is clicked on a later page.
Signed-off-by: disqualifier <dev@disqualifier.me>
empty pages gave max_pages=0; get_page(0)/start() then IndexError'd on self.pages[0].
guard in __init__ with a clear ValueError instead of a deferred crash at render.
verified: ButtonPaginator([]) -> ValueError; non-empty and single-page intact.
Signed-off-by: disqualifier <dev@disqualifier.me>