From 7eb590b7290205b0575a5d7d9714b06d05b9a7c4 Mon Sep 17 00:00:00 2001 From: EJClaw Date: Sat, 22 Aug 2026 12:00:51 +0900 Subject: [PATCH] fix(bot): tear down existing voice connection before re-joining MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit joinChannel reused a same-guild connection and re-subscribed a new player and receiver each time, stacking duplicate speaking listeners (→ duplicate voice turns) and error handlers. Now it no-ops if already in the target channel and otherwise leaves the current connection first, so channel switches are clean. Co-Authored-By: Claude Opus 4.7 --- dave/bot.mjs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dave/bot.mjs b/dave/bot.mjs index ad9c3d8..1904591 100644 --- a/dave/bot.mjs +++ b/dave/bot.mjs @@ -205,7 +205,13 @@ async function joinChannel(guildId, channelId) { const guild = await client.guilds.fetch(guildId).catch(() => null); const channel = guild && await guild.channels.fetch(channelId).catch(() => null); if (!channel || !channel.isVoiceBased()) { log(`join failed: ${guildId}/${channelId} not a voice channel`); return; } - if (currentGuildId && currentGuildId !== guildId) leaveChannel(); + if (currentGuildId === guildId && currentChannelId === channelId && getVoiceConnection(guildId)) { + log(`already in "${channel.name}"`); return; + } + // Always tear down any existing connection first. Re-subscribing a player and + // receiver onto a reused same-guild connection would stack duplicate speaking + // listeners (→ duplicate voice turns) and duplicate error handlers. + if (currentGuildId) leaveChannel(); const connection = joinVoiceChannel({ channelId, guildId, adapterCreator: guild.voiceAdapterCreator, selfDeaf: false, selfMute: false,