discordjs/discord.js · error · DiscordjsTypeError
InvalidElement
InvalidElement
Error message
Supplied ${type} ${name} includes an invalid element: ${elem} What it means
InvalidElement is thrown when a scope inside the scopes array is not a recognized OAuth2Scopes value. generateInvite() validates every element against Object.values(OAuth2Scopes) and reports the first offending element in the message, so malformed scopes never reach the generated URL.
Source
Thrown at packages/discord.js/src/client/Client.js:760
throw new DiscordjsTypeError(ErrorCodes.InvalidMissingScopes);
}
if (!Array.isArray(scopes)) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'scopes', 'Array of Invite Scopes', true);
}
if (!scopes.some(scope => [OAuth2Scopes.Bot, OAuth2Scopes.ApplicationsCommands].includes(scope))) {
throw new DiscordjsTypeError(ErrorCodes.InvalidMissingScopes);
}
if (!scopes.includes(OAuth2Scopes.Bot) && options.permissions) {
throw new DiscordjsTypeError(ErrorCodes.InvalidScopesWithPermissions);
}
const validScopes = Object.values(OAuth2Scopes);
const invalidScope = scopes.find(scope => !validScopes.includes(scope));
if (invalidScope) {
throw new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array', 'scopes', invalidScope);
}
const query = makeURLSearchParams({
client_id: this.application.id,
scope: scopes.join(' '),
disable_guild_select: options.disableGuildSelect,
});
if (options.permissions) {
const permissions = PermissionsBitField.resolve(options.permissions);
if (permissions) query.set('permissions', permissions.toString());
}
if (options.guild) {
const guildId = this.guilds.resolveId(options.guild);
if (!guildId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options.guild', 'GuildResolvable');
query.set('guild_id', guildId);
}View on GitHub (pinned to a81ed8a306)
Solutions
- Use only values from the imported OAuth2Scopes enum, e.g. [OAuth2Scopes.Bot, OAuth2Scopes.ApplicationsCommands]
- Check casing and spelling against the OAuth2Scopes enum definition
- Filter/validate the scopes array before calling: scopes.every(s => Object.values(OAuth2Scopes).includes(s))
Example fix
// before
const link = client.generateInvite({ scopes: ['bot', 'application.commands'] });
// after
const { OAuth2Scopes } = require('discord.js');
const link = client.generateInvite({ scopes: [OAuth2Scopes.Bot, OAuth2Scopes.ApplicationsCommands] }); Defensive patterns
Strategy: validation
Validate before calling
const valid = Object.values(OAuth2Scopes);
const bad = scopes.filter((s) => !valid.includes(s));
if (bad.length) throw new Error(`Unknown scopes: ${bad.join(', ')}`); Type guard
const allScopesValid = (scopes) => Array.isArray(scopes) && scopes.every((s) => Object.values(OAuth2Scopes).includes(s));
Try / catch
try {
const link = client.generateInvite({ scopes });
} catch (err) {
if (err.code === 'InvalidElement') console.error(`Bad scope in list: ${err.message}`);
else throw err;
} Prevention
- Source every scope from the OAuth2Scopes enum
- Never type scope strings by hand or from memory
- Validate user/config-supplied scope lists against the enum before use
- Use TypeScript with OAuth2Scopes[] typing for compile-time safety
When it happens
Trigger: scopes: ['bots'], scopes: ['BOT'], scopes: ['application.commands'] — strings not matching any OAuth2Scopes enum member, including wrong casing or hyphenated variants.
Common situations: Hand-typing scope strings from memory or from outdated documentation; mixing in custom scopes; case errors ('Bot' vs 'bot'); migrating from v11-era permission strings.
Understand the failure class
Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.
Related errors
- InvalidMissingScopes
- InvalidScopesWithPermissions
- ClientNotReady
- ClientMissingIntents
- ClientInvalidOption
AI-assisted analysis of discordjs/discord.js@a81ed8a306 (2026-08-30).
Data as JSON: /api/errors/2e33fdfa9c268a74.
Report an issue: GitHub.