

EDIT: Updated the screenshot due to a mistake on my part when testing with eval. The issue still persisted at the time whether I had .voiceChannel or .channel, since the argument on my end is that I would get a null value for both.
This happens occasionally and I'm not sure what causes it. Sometimes my bot will be returning a voiceConnection for a guild, but it's not visibily in any voice channels and the voice channel is undefined. Calling .disconnect() seems to do nothing, as the bot still returns a voiceConnection.
This has been occurring since v9 but hasn't been reliably reproducible. I can try using node v7 too but it's hard for me to figure out what's causing it. I think it's a timeout issue where the bot may disconnect as soon as it connects, but the library still thinks there's a voice connection. Is there a way to absolutely force disconnect to destroy a connection just in case?
I've also tried some ultra defensive coding around it as well...

But like I said, .disconnect() does nothing after this starts happening for a guild and this code ends up failing, saying there's a voice connection. If I restart my node process, it works as intended again but until I do that, it seems to not work after that.
The status is 4, not 0:

Code example:

What else should I provide?
I'm also getting this. It didnt occur previously for me however on v11.0.0 After upgrading this weekend to v11.1.0 it started to happen.
As you can see, I made a PR (referenced above) to attempt to fix this. Please try it out and let me know if there are any unexpected issues and whether it fixes the issue for you.
@aemino I'll try it and leave it up for a couple days and report back.
@JMTK any issues with the PR he made?
@iCrawl @aemino Hi all, sorry for the late response. I was out of town.
Something similar still happens, but maybe less frequently(?). It seems like there's some other place where this desync happens. I've had some users report that the bot can be summoned/dismissed from a voice channel, but when they try to summon it, it never appears, but still behaves as though it is since it thinks there's a valid voice connection.
Yo dude, you do know it's connection.channel right? not connection.voiceChannel... https://northstarofficial.com/uploader/files/EdibleDerpy/hhd1zbi.png
https://discord.js.org/#/docs/main/master/class/VoiceConnection?scrollTo=channel
How was this not noticed before? 馃槀馃槀馃槀
I don't even see your problem, other then the voiceChannel part. I don't know how people have not realized this... .voiceChannel has never been a method on a voiceConnection. Please do some more research before marking something as a bug. Like holy hell. If this is a bigger issue then enlighten me. Because I don't really see your issue. My bot never sticks around a voice connection and never hangs in a channel unless I restart it. Maybe it's because your storing the items in the guild. Which I used to do at one point then it all stopped working so I moved to maps. If you want a general understand of maps to be used in a voice bot let me know and I will be happy to write something up for you to see how maps work. Of course only if you don't already know about maps.
Maps are a way better way of doing it and being able to delete that guilds map upon disconnect is much better.
@EdibleDerpy @CakeNetwork Oh yeah sorry I meant to edit the comment on this but I realized that like right after. If you look at the actual code samples I posted, I use connection.channel. I'll update the eval screenshots once it happens again but nowhere in my code am I using .voiceChannel, just a minor mistake on my part but the issue still persists for me.

I don't think I'm ever modifying the guild object directly. I don't believe this is a visual issue on Discord. The bot has been in situations where the voice connection was active and either have a valid voice channel.
I added a couple of more disconnect()s for other conditions today, so hopefully that will fix it on my end. I personally think that @aemino's PR is the correct fix for more cleanly disconnecting under certain scenarios.
Alright, well technically you are modifying the guild object. You are putting the voice connection inside of the guild. That means you can pull it with msg.guild.connection or something similar I would recommend doing something like the example below.
const Dispatchers = new Map();
msg.member.voiceChannel.join().then(connection => {
let D = {
connection: connection
}
Dispatchers.set(msg.guild.id, D);
})
// Then later in your code you can pull that by doing
let Dispatcher = Dispatchers.get(msg.guild.id); // This will contain the entire D object from when we connected and defined it.
console.log(Dispatcher.connection); // Output: The VoiceConnection output.
Let me see if I can write you a full working example that will loop a song from YouTube
@EdibleDerpy Is it not part of the Guild object natively or are you referring to something else?
https://discord.js.org/#/docs/main/stable/class/Guild?scrollTo=voiceConnection
Actually you are right in a sense, I just realized that it's actually stored in the guild by the library. That's not how I'd recommend it being done though. It's a good thing for quick and easy like eval access to the voiceConnection. But I would still store it in something like a map let me give you a quick example.
In regards to where I loop through the voiceConnections property in the third screenshot: I had an old issue where the .voiceConnection property of a guild would be undefined, so I had to try and loop through the bots .voiceConnections property instead to look for it. I think that was v9 and it's been fixed since that condition probably never gets met anymore so I could remove it.
Here is some stuff for you to look over if you wanna take a look at how this works.
const ytdl = require('ytdl-core'); // npm i ytdl-core
const Dispatchers = new Map(); // This is where the connections and everything about the stream/msg that triggered it. You can put anything in there.
function play(connection) {
let Dispatch = Dispatchers.get(msg.guild.id);
let stream = ytdl('https://www.youtube.com/watch?v=Hb4fzFk4U-s', { format: 'audioonly' })
let dispatcher = connection.playStream(stream, { volume: 1 });
dispatcher.once('end', (r) => {
play(connection);
})
Dispatch.dispatcher = dispatcher;
}
msg.member.voiceChannel.join().then(connection => {
play(connection);
let Dispatch = {
connection: connection,
msg: msg
}
Dispatchers.set(msg.guild.id, Dispatch);
})
// Then later in your code you can pull that by doing
let Dispatcher = Dispatchers.get(msg.guild.id); // This will contain the entire D object from when we connected and defined it.
console.log(Dispatcher.connection); // Output: The VoiceConnection output.
Most helpful comment
Yo dude, you do know it's
connection.channelright? notconnection.voiceChannel... https://northstarofficial.com/uploader/files/EdibleDerpy/hhd1zbi.pnghttps://discord.js.org/#/docs/main/master/class/VoiceConnection?scrollTo=channel