Changelog - Version 5.7.10 (2026-05-25)
Version Information
- Updated version from 5.7.9 to 5.7.10
- Fix for the Stable bot:
!addpointsand!removepointsnow credit/debit the targeted user instead of the moderator running the command,!points @usercorrectly reports the targeted user’s balance, and the underlying points helper is no longer prone to race conditions
Bug Fixes
- Fixed
!addpoints @user Xcrediting the moderator instead of the targetaddpoints_commandwas usingctx.author.idfor both the SELECT and UPDATE that wrote tobot_points, so the credit always went to the moderator running the command. The chat reply interpolated the target user’s name string, so it looked like the target had received the points — but the row that actually got incremented was the moderator’s.- The handler now resolves the target via Twitch Helix (
fetch_users(names=[lookup_name])) and uses the returneduser_idfor the DB write, so the credit lands on the right account.
- Fixed
!removepoints @user Xdebiting the moderator instead of the target- Same root cause as the addpoints bug — the previous code used
ctx.author.idfor the SELECT/UPDATE. The handler now resolves the target via Helix and debits the correct row.
- Same root cause as the addpoints bug — the previous code used
- Fixed
!points @userignoring the @user argumentpoints_commandhad nouserparameter in its signature, so TwitchIO silently discarded the @user argument. Running!points @someonealways reported the caller’s points and named the caller in the reply.- The handler now accepts an optional
userargument. When supplied, it resolves the target via Helix and reports that user’s balance ("@target has N points."). When omitted, behaviour is unchanged ("@caller, you have N points.").
- Fixed points read-modify-write race that could lose increments
- The
bot_pointsupdates were doingSELECT points → compute new total → UPDATE points, which is not atomic. When two handlers touched the same row concurrently (for example!addpointsrunning at the same time as the per-message chat-points credit), one UPDATE could clobber the other’s increment. - Credits now use a single
INSERT ... ON DUPLICATE KEY UPDATE points = points + VALUES(points)statement so the increment can’t be lost. Debits useUPDATE ... SET points = GREATEST(0, points - amount)so concurrent writes can’t drive a row negative. The chat reply re-reads the row after the write so the displayed total always matches the database state.
- The
Technical Details
points_command: signature nowasync def points_command(self, ctx, user: str = None). Whenuseris provided the handler does a Helix lookup, switches to the resolved target’s id/name for the DB read, and uses third-person phrasing in the reply. The excluded-users check now matches the target name rather than the caller’s name.addpoints_command: removed theuser_id = str(ctx.author.id)assignment that caused the credit to land on the moderator’s row. Resolves the target viaself.fetch_users(names=[lookup_name]), then atomically upserts the credit and re-SELECTs the new total for the chat reply. A[ADD POINTS]info log line now records the resolvedtarget_user_idalongside the caller and amount so future point-tracking reports can be verified.removepoints_command: same target-resolution and atomic-debit changes as addpoints. Adds a[REMOVE POINTS]info log line.
Thank you for your feedback and support!
As always, your feedback is appreciated. Please report any issues, bugs, or suggestions in the #ticket-info channel on our Discord server. You can also submit feedback and bug reports directly on our support website: https://support.botofthespecter.com/