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

  1. Use only values from the imported OAuth2Scopes enum, e.g. [OAuth2Scopes.Bot, OAuth2Scopes.ApplicationsCommands]
  2. Check casing and spelling against the OAuth2Scopes enum definition
  3. 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

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


AI-assisted analysis of discordjs/discord.js@a81ed8a306 (2026-08-30). Data as JSON: /api/errors/2e33fdfa9c268a74. Report an issue: GitHub.