Discord Player
Plugins

Operations

How handlers are chosen, ordered, cancelled, and when a handler declines.

You are reading the v8 docsDev

A plugin registers handlers for named operations. Each operation has a dispatch policy that decides how results are combined.

Built-in operations

OperationPolicyResult
search.query.matchcollectScore from each plugin
search.query.resolvefirstTracks and an optional playlist
track.streamfirstA media source
track.relatedfirstRelated tracks for autoplay
track.bridgefirstA fallback source when the track's own provider cannot stream
stream.transformpipeA replacement encoded stream
lyrics.searchcollectLyrics results
track.stream.resolvedbroadcastNotification only

Dispatch policies

PolicyBehavior
firstUse the first result that is not undefined
collectReturn all results as a list
pipePass each result to the next handler
broadcastCall every handler. No result

Priority and scores

ctx.on('search.query.match', ({ query }) => (query.startsWith('https://') ? { score: 90 } : null), {
  priority: 10,
});

Handlers with higher priority run first. For equal priority, a higher match score wins, then registration order. The Player resolves candidates in that order until one returns tracks.

Declining

ReturnMeaning
undefinedThis handler declines. The next one runs
nullA real result of "no match" for operations that allow it
A throwA failure. The Player does not try another plugin

Target or block plugins

await player.search(query, { searchEngine: 'example.direct-audio' });
await player.search(query, { searchEngine: 'ext:example.direct-audio' }); // Legacy extractor syntax

The blockExtractors option disables plugins by ID. It applies to matching, direct execution, stream resolution, and bridging.

import { Player } from 'discord-player';

const player = new Player({ blockExtractors: ['example.direct-audio'], send });

Cancellation and errors

Every handler receives { signal }, which aborts when the caller cancels or the plugin is removed. Check it during slow work:

ctx.on('track.stream', async ({ track }, { signal }) => {
  signal.throwIfAborted();

  return { url: track.url };
});

A failing handler rejects with a PluginError that names the plugin and operation.

Continue reading

Custom operations

On this page