discordjs/discord.js · error · DiscordjsTypeError

CommandInteractionOptionEmpty

CommandInteractionOptionEmpty

Error message

CommandInteractionOptionEmpty

What it means

CommandInteractionOptionEmpty is thrown by _getTypedOption when an option is required, has the correct type, but all of its relevant value properties (e.g. value, user, channel, member) are null/undefined. This happens when Discord delivers an option object that carries no usable value for the requested type.

Source

Thrown at packages/discord.js/src/structures/CommandInteractionOptionResolver.js:112

  /**
   * Gets an option by name and property and checks its type.
   *
   * @param {string} name The name of the option.
   * @param {ApplicationCommandOptionType[]} allowedTypes The allowed types of the option.
   * @param {string[]} properties The properties to check for `required`.
   * @param {boolean} required Whether to throw an error if the option is not found.
   * @returns {?CommandInteractionOption} The option, if found.
   * @private
   */
  _getTypedOption(name, allowedTypes, properties, required) {
    const option = this.get(name, required);
    if (!option) {
      return null;
    } else if (!allowedTypes.includes(option.type)) {
      throw new DiscordjsTypeError(ErrorCodes.CommandInteractionOptionType, name, option.type, allowedTypes.join(', '));
    } else if (required && properties.every(prop => option[prop] === null || option[prop] === undefined)) {
      throw new DiscordjsTypeError(ErrorCodes.CommandInteractionOptionEmpty, name, option.type);
    }

    return option;
  }

  /**
   * Gets the selected subcommand.
   *
   * @param {boolean} [required=true] Whether to throw an error if there is no subcommand.
   * @returns {?string} The name of the selected subcommand, or null if not set and not required.
   */
  getSubcommand(required = true) {
    if (required && !this._subcommand) {
      throw new DiscordjsTypeError(ErrorCodes.CommandInteractionOptionNoSubcommand);
    }

    return this._subcommand;
  }

View on GitHub (pinned to a81ed8a306)

Solutions

  1. Verify the properties you expect exist for the option's actual type (a Channel option has `channel`, a User option has `user` and `member`, etc.)
  2. Re-check the command registration matches the builder and redeploy commands
  3. Make the accessor non-required and validate the returned null yourself for optional input
  4. Log `interaction.options.data` to see exactly what Discord populated for the option

Example fix

// before
const user = interaction.options.getUser('user', true); // option is actually a channel-type
// after
const user = interaction.options.getUser('user'); // returns null safely, then validate
if (!user) return interaction.reply({ content: 'Please provide a user.', ephemeral: true });
Defensive patterns

Strategy: validation

Validate before calling

const opt = interaction.options.data.find(o => o.name === 'user');
if (!opt || (opt.user == null && opt.value == null)) {
  return interaction.reply({ content: 'Please provide a user.', ephemeral: true });
}

Type guard

function hasOptionValue(opt) {
  return opt != null && ['value','user','member','channel','role','attachment'].some(p => opt[p] != null);
}

Try / catch

try {
  const user = interaction.options.getUser('user', true);
} catch (err) {
  if (err.code === 'CommandInteractionOptionEmpty') {
    return interaction.reply({ content: 'The user option came back empty.', ephemeral: true });
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling a typed accessor with required=true for an option whose resolved object has all checked properties null/undefined — e.g. a user option where neither value nor user/member is populated; usually due to desync between the command registration and handler expectations or an unfilled-but-required option sent by Discord.

Common situations: Accessing option value properties that don't exist for that option type (expecting `user` on a string option); stale command registration after changing option types; autocomplete flows where values are not yet resolved; race with command registration updates.

Related errors


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