The dashboard showed the toggle on. The status command said enabled. No member had ever received a role.
I found this while working on something else. A dashboard to-do claimed that auto-roles and my verification gate "both act on join and conflict", and asked me to add a warning about the clash. Before building the warning I went to check how the two interact.
They don't interact, because auto-roles had no code path on join at all. The member-join handler never touched them. The only place that granted auto-roles was the handler that runs when a member passes a verification gate. So the feature worked exactly where a gate was enabled and nowhere else: 2 guilds out of the 127 that had auto-roles switched on with a role selected.
Why nothing noticed
Everything around the feature agreed with itself. The settings page read the row, the status command read the row, and the row said enabled. Nothing checked the outcome: whether a member actually ended up holding the role. A feature can be fully configured and never run.
The fix, and one decision worth stealing
Adding a grant on join is easy. The interesting part is what happens when a gate is on. A verification gate exists so a member holds no roles until they pass it. Granting on join would hand out exactly the roles the gate is there to withhold.
So the join path checks the gate's own enabled flag and steps aside when the gate is on. The gate keeps ownership. The check reads that local flag instead of watching what the gate did, because the gate call is fire-and-forget and its outcome is not visible from the join handler. If the two ever disagree, the member gets nothing. That is deliberate: a missing role is a support message, a role handed to someone the gate meant to stop is an incident.
The same planning function feeds both the join path and a backfill for existing members, so the prechecks cannot drift apart between the two.
What I took from it
- Verify the premise of a bug report before building the fix. The spec described a conflict that did not exist. The real bug was a missing branch.
- "Enabled" in a settings page proves a row exists, not that the feature runs. Test the outcome.
- When two paths can grant the same thing, decide which one fails safe before you write either.
I build Akiko, a Discord bot with AI chat that remembers you, plus economy, music, moderation and a web dashboard. Free to add: https://i.hep.gg/akiko
Top comments (0)