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

  1. Change the `extension` option to one of the allowed values listed in the error message (usually 'webp', 'png', 'jpg', 'jpeg', or 'gif').
  2. Import ALLOWED_EXTENSIONS (or ALLOWED_STICKER_EXTENSIONS for sticker URLs) from @discordjs/rest to validate or enumerate valid values at runtime.
  3. 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.
  4. 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

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


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