discordjs/discord.js · error · RangeError
Invalid extension provided: ${extension} Must be one of: ${a
Error message
Invalid extension provided: ${extension}
Must be one of: ${allowedExtensions.join(', ')} What it means
makeURL() in CDN.ts builds Discord CDN asset URLs and validates the requested image extension against the list of extensions allowed for that asset type (e.g. ALLOWED_EXTENSIONS for most images, ALLOWED_STICKER_EXTENSIONS for stickers). Before constructing the URL it lowercases the extension and throws this RangeError if it isn't in the allowed list. It exists to fail fast on invalid input rather than produce broken CDN links.
Source
Thrown at packages/rest/src/lib/CDN.ts:389
*
* @param route - The base cdn route
* @param options - The extension/size options for the link
*/
private makeURL(
route: string,
{
allowedExtensions = ALLOWED_EXTENSIONS,
base = this.cdn,
extension = 'webp',
size,
animated,
}: Readonly<MakeURLOptions> = {},
): string {
// eslint-disable-next-line no-param-reassign
extension = String(extension).toLowerCase();
if (!allowedExtensions.includes(extension)) {
throw new RangeError(`Invalid extension provided: ${extension}\nMust be one of: ${allowedExtensions.join(', ')}`);
}
if (size && !ALLOWED_SIZES.includes(size)) {
throw new RangeError(`Invalid size provided: ${size}\nMust be one of: ${ALLOWED_SIZES.join(', ')}`);
}
const url = new URL(`${base}${route}.${extension}`);
if (animated !== undefined) {
url.searchParams.set('animated', String(animated));
}
if (size) {
url.searchParams.set('size', String(size));
}
return url.toString();
}View on GitHub (pinned to a81ed8a306)
Solutions
- Change the `extension` option to one of the allowed values listed in the error message (usually 'webp', 'png', 'jpg', 'jpeg', or 'gif').
- Import ALLOWED_EXTENSIONS (or ALLOWED_STICKER_EXTENSIONS for sticker URLs) from @discordjs/rest to validate or enumerate valid values at runtime.
- If the extension comes from user input or a file path, normalize it (lowercase, strip a leading dot) and fall back to 'webp' (the default) when it isn't in the allowed set.
- Omit the `extension` option entirely to get the default 'webp'.
Example fix
// before
const url = user.displayAvatarURL({ extension: 'svg' });
// RangeError: Invalid extension provided: svg
// after
const ext = ['webp', 'png', 'jpg', 'jpeg', 'gif'].includes(userInput) ? userInput : 'webp';
const url = user.displayAvatarURL({ extension: ext }); Defensive patterns
Strategy: validation
Validate before calling
import { ALLOWED_EXTENSIONS } from '@discordjs/rest';
function assertValidExtension(ext: string) {
const normalized = ext.toLowerCase().replace(/^\./, '');
if (!ALLOWED_EXTENSIONS.includes(normalized as never)) {
throw new RangeError(`Unsupported extension: ${normalized}`);
}
return normalized;
} Type guard
const isImageExtension = (v: string): v is ImageExtension => (['webp', 'png', 'jpg', 'jpeg', 'gif'] as const).includes(v as ImageExtension);
Try / catch
try {
url = user.displayAvatarURL({ extension: ext });
} catch (error) {
if (error instanceof RangeError && error.message.startsWith('Invalid extension')) {
url = user.displayAvatarURL(); // default webp
} else {
throw error;
}
} Prevention
- Use the ImageExtension type so invalid extensions are caught at compile time.
- Never build extensions from raw file paths or unvalidated user input.
- Rely on the default 'webp' unless a specific format is required (e.g. 'gif' for animated avatars).
- Keep a whitelist map of permitted formats in your app and check before calling URL builders.
When it happens
Trigger: Calling any CDN URL builder (appAsset, appIcon, avatarDecoration, channelIcon, defaultAvatar, discoverySplash, avatar, banner, emoji, icon, etc.) with an `extension` option that is not one of the allowed values ('webp', 'png', 'jpg', 'jpeg', 'gif' — or sticker-specific ones), including misspellings, uppercase strings that aren't normalized by the caller's type (e.g. 'PNG' actually works since it lowercases, but 'bmp' or 'svg' never work), or non-string values coerced via String().
Common situations: Hardcoding an extension like 'svg' or 'jpg' when only webp/png/gif are allowed; copying code that used a sticker URL builder's extension for a regular image or vice versa; building extensions dynamically from user input or file paths; upgrading discord.js where allowed extension sets changed.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Invalid size provided: ${size} Must be one of: ${ALLOWED_SIZ
- ShardingShardMiscalculation
- CommandInteractionOptionInvalidChannelType
- InvalidType
- Cannot set an interval greater than 4 hours
AI-assisted analysis of discordjs/discord.js@a81ed8a306 (2026-08-30).
Data as JSON: /api/errors/2ef9f36bbd778603.
Report an issue: GitHub.