Troubleshooting
Find solutions to common problems and errors when using Moonlink.js.
Troubleshooting Common Issues
This guide helps you resolve common issues you might encounter while using Moonlink.js. If you can't find a solution here, feel free to ask for help on our Discord server.
Connection Issues
Problems related to connecting to Lavalink or voice channels.
Error Connecting to Lavalink
Symptom: You see
Solution:
nodeError
events with messages like ECONNREFUSED
, 401 Unauthorized
, or Invalid password
.
Solution:
- Check Lavalink Status: Ensure your Lavalink server is running correctly.
- Verify Configuration: Double-check the
host
,port
, andpassword
in your Manager configuration. They must exactly match your Lavalinkapplication.yml
. - Firewall: Make sure your firewall is not blocking the connection between your bot and the Lavalink server.
Manager Config
application.yml
const manager = new Manager({
nodes: [{
host: 'localhost', // Must match Lavalink host
port: 2333, // Must match Lavalink port
password: 'youshallnotpass', // Must match Lavalink password
}],
// ...
});
Bot Doesn't Join Voice Channel
Symptom: The bot doesn't join the voice channel, and no sound is played. You might not see any errors.
Solution:
Solution:
sendPayload
Function: Ensure you have correctly implemented thesendPayload
function. This function is crucial for sending voice updates to Discord.- Intents: Verify that you have enabled the necessary Gateway Intents for your Discord client, especially
Guilds
andGuildVoiceStates
. packetUpdate
: Make sure you are forwarding raw voice packets to the manager usingclient.on('raw', (packet) => manager.packetUpdate(packet));
.
Required Code
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildVoiceStates, // Required for voice
],
});
const manager = new Manager({
// ... nodes
sendPayload: (guildId, payload) => {
const guild = client.guilds.cache.get(guildId);
if (guild) guild.shard.send(JSON.parse(payload));
},
});
client.on('raw', (packet) => {
manager.packetUpdate(packet);
});
Node Disconnects Frequently
Symptom: The
Solution:
nodeDisconnect
event is emitted frequently, and the bot experiences interruptions.
Solution:
- Lavalink Server Health: Check the logs and resource usage (CPU/Memory) of your Lavalink server. It might be overloaded or crashing.
- Network Stability: Ensure a stable network connection between your bot and the Lavalink server.
- Retry Settings: Adjust the
retryAmount
andretryDelay
options in your node configuration to give the bot more time to reconnect.
Node Configuration
{
host: 'localhost',
port: 2333,
password: 'youshallnotpass',
retryAmount: 10, // Increase attempts
retryDelay: 15000 // Increase delay to 15 seconds
}
No Active Lavalink Node
Symptom: Searches fail with an
Solution:
empty
result, and you see debug messages like No connected node available to handle the request.
or No available nodes
.
Solution:
- Node Status: Ensure at least one of your Lavalink nodes in the
Manager
configuration is running and accessible from your bot. - Initial Connection: The
nodeReady
event should be emitted for each node that successfully connects when your bot starts. If you don't see this, re-check your node configuration (host
,port
,password
). - Node Failure: If a node disconnects, Moonlink.js will attempt to reconnect based on your
retryAmount
andretryDelay
settings. If all nodes are offline, all player actions and searches will fail until one reconnects. - Check for
nodeError
: Listen for thenodeError
event to catch connection problems as they happen.
Event Listener
manager.on('nodeError', (node, error) => {
console.error(`Node ${node.identifier} encountered an error:`, error.message);
});
Playback Issues
Problems related to playing tracks, audio quality, and track events.
No Sound is Playing
Symptom: The bot joins the voice channel, a
Solution:
trackStart
event is emitted, but no audio is heard.
Solution:
- Lavalink Logs: Check the Lavalink server console for errors like
TrackExceptionEvent
orWebSocketClosedEvent
. These often provide clues. - Track Loading: Ensure the track was loaded successfully. A
loadFailed
result frommanager.search()
will cause this. - Volume: Make sure the player's volume is not set to 0. Also, check that the bot is not server-muted.
Track Stuck or Exception Events
Symptom: You receive
Solution:
trackStuck
or trackException
events.
Solution:
trackStuck
: This usually indicates a network issue between Lavalink and the audio source (e.g., YouTube). It can be temporary. You can handle this by skipping to the next track.trackException
: This means Lavalink failed to play the track. Theexception
payload will contain details. Common reasons include age-restricted content, region-locked videos, or private tracks. It's best to log the error and skip the track.
Event Handling
manager.on('trackStuck', (player, track, threshold) => {
console.error(`Track ${track.title} got stuck. Threshold: ${threshold}ms`);
player.skip();
});
manager.on('trackException', (player, track, exception) => {
console.error(`Track ${track.title} failed to play:`, exception);
player.skip();
});
Choosing Between Native Sources and LavaSrc
Context: Moonlink.js has its own internal (native) sources for platforms like Spotify and Deezer. However, for full-featured and more reliable playback, using a Lavalink plugin like LavaSrc is highly recommended.
Problem: You're not sure why Spotify/Deezer links aren't working as expected, or you want the best performance.
Solution:Note: If you choose to use the native Spotify source (by setting
Problem: You're not sure why Spotify/Deezer links aren't working as expected, or you want the best performance.
Solution:
- Use LavaSrc: For the best experience, install the LavaSrc plugin on your Lavalink server.
- Disable Native Sources: To ensure all requests go through LavaSrc, disable the native sources in the manager options. This prevents potential conflicts or unexpected behavior.
clientId
and clientSecret
in the Moonlink.js manager options. Those should be configured in your Lavalink server's application.yml
file for the LavaSrc plugin. Manager Config for LavaSrc
Lavalink application.yml for LavaSrc
const manager = new Manager({
nodes: [/* ... */],
sendPayload: (guildId, payload) => { /* ... */ },
options: {
// Disable internal sources to prioritize LavaSrc
disableNativeSources: true,
}
});
disableNativeSources: false
), you must provide the clientId
and clientSecret
in the manager.options.spotify
object. However, this method is generally less reliable for playback.General Errors & Tips
Common JavaScript errors and debugging advice.
TypeError: Cannot read properties of undefined
Symptom: You get an error like
Solution: This almost always means you are trying to access a property or method on an object that is
TypeError: Cannot read properties of undefined (reading 'play')
.
Solution: This almost always means you are trying to access a property or method on an object that is
undefined
. The most common cause in Moonlink.js is trying to use a player that doesn't exist.Always check if the player exists before using it:const player = manager.players.get(guildId);
if (!player) {
console.log('No player found for this guild.');
return;
}
// Now it's safe to use the player
player.pause();
Using the Debug Event
Symptom: You are not sure what is happening internally.
Solution: Moonlink.js provides a
Solution: Moonlink.js provides a
debug
event that emits detailed information about internal operations. This is incredibly useful for understanding the library's behavior and diagnosing complex issues.manager.on('debug', (message) => {
console.log(`[MOONLINK DEBUG] ${message}`);
});
Checking Lavalink Logs
Symptom: You suspect the issue might be on the Lavalink side.
Solution: Always check the console output of your Lavalink server. It provides crucial information about track loading, playback errors, and connection statuses. Look for messages containing
Solution: Always check the console output of your Lavalink server. It provides crucial information about track loading, playback errors, and connection statuses. Look for messages containing
WARN
, ERROR
, or Exception
.Search Fails or Returns No Tracks
Symptom:
Solution:
manager.search()
returns a loadType
of empty
or error
, even for valid queries.
Solution:
- Source Fallback: If you are using
enableSourceFallback: true
, a search might fail on the primary source and then silently fail on fallback sources if none are available or suitable. Enable thedebug
event to see the search process in detail. - Node Capabilities: When you search for a track from a specific source (e.g., Spotify), Moonlink.js tries to find a connected node that has the required capability (e.g.,
search:spotify
). If no such node is found, the search will fail for that source. Ensure your Lavalink plugins (like LavaSrc) are correctly loaded and reported by the node. - Track Resolution: If a track from a specific source (e.g., a Spotify track in the queue) is about to be played on a node that doesn't support it, the
play
function will attempt to find a new, suitable node. If that fails, it will try to search for the track by its title and author on a default platform (like YouTube). If all these steps fail, playback will stop. Check the debug logs for messages likeNo suitable node found
orGeneric search fallback failed
.
Auto-Resume Not Working
Symptom: Players and queues are not restored after a bot restart, even with
Solution:
autoResume: true
.
Solution:
- Database Enabled: The
autoResume
feature depends on the internal database to store player state. Ensure you have not setdisableDatabase: true
in the manager options. - Persistent Storage: The database writes to files in the
src/datastore
directory. Make sure your deployment environment has persistent storage and that these files are not deleted between restarts. - Graceful Shutdown: While not strictly required, ensuring a graceful shutdown allows the database to compact and save its final state correctly, which can prevent data loss.