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
- 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.)
- Re-check the command registration matches the builder and redeploy commands
- Make the accessor non-required and validate the returned null yourself for optional input
- 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
- Check the option object shape matches its type before accessing value properties
- Redeploy commands when schema changes to avoid stale registrations
- Treat required=false and validate nulls explicitly for robustness
- Log options.data when debugging empty payloads
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
- CommandInteractionOptionNotFound
- CommandInteractionOptionType
- CommandInteractionOptionNoSubcommand
- CommandInteractionOptionNoSubcommandGroup
- CommandInteractionOptionInvalidChannelType
AI-assisted analysis of discordjs/discord.js@a81ed8a306 (2026-08-30).
Data as JSON: /api/errors/a57d8456f95ab67b.
Report an issue: GitHub.