discordjs/discord.js · error · RangeError

Invalid size provided: ${size} Must be one of: ${ALLOWED_SIZ

Error message

Invalid size provided: ${size}
Must be one of: ${ALLOWED_SIZES.join(', ')}

What it means

makeURL() in CDN.ts validates the requested image `size` against ALLOWED_SIZES (the powers of 2 from 16 to 4096 that Discord's CDN accepts). If a size is given that isn't in that list, it throws this RangeError instead of generating a URL Discord would reject. Discord only serves assets at specific fixed dimensions, so arbitrary sizes like 100 or 500 are invalid.

Source

Thrown at packages/rest/src/lib/CDN.ts:393

	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. Snap the size to the nearest allowed power of two: one of 16, 32, 64, 128, 256, 512, 1024, 2048, 4096.
  2. Import ALLOWED_SIZES from @discordjs/rest and pick the closest allowed value programmatically before calling the URL builder.
  3. Omit the `size` option entirely to get the asset's default (often 128px for avatars).
  4. If the size comes from config or user input, validate it against ALLOWED_SIZES at load time and fail/normalize early.

Example fix

// before
const url = user.displayAvatarURL({ size: 100 }); // RangeError
// after
import { ALLOWED_SIZES } from '@discordjs/rest';
const size = ALLOWED_SIZES.reduce((a, b) => (Math.abs(b - 100) < Math.abs(a - 100) ? b : a));
const url = user.displayAvatarURL({ size }); // 128
Defensive patterns

Strategy: validation

Validate before calling

import { ALLOWED_SIZES } from '@discordjs/rest';
function nearestSize(wanted: number): ImageSize {
  return ALLOWED_SIZES.reduce((a, b) => (Math.abs(b - wanted) < Math.abs(a - wanted) ? b : a));
}

Type guard

const isImageSize = (v: number): v is ImageSize =>
  [16, 32, 64, 128, 256, 512, 1024, 2048, 4096].includes(v);

Try / catch

try {
  url = user.displayAvatarURL({ size });
} catch (error) {
  if (error instanceof RangeError && error.message.startsWith('Invalid size')) {
    url = user.displayAvatarURL({ size: nearestSize(size) });
  } else {
    throw error;
  }
}

Prevention

When it happens

Trigger: Passing `size` to any CDN URL builder (appAsset, appIcon, avatarDecoration, channelIcon, defaultAvatar, discoverySplash, avatar, banner, emoji, etc.) with a value not in [16, 32, 64, 128, 256, 512, 1024, 2048, 4096] — e.g. size: 100, size: 512.0 coerced oddly, a value read from config in arbitrary units, or a computed size like a user's avatar rendered width.

Common situations: Using a UI display width (e.g. 48, 100, 250) directly as the size; computing sizes dynamically (size * 1.5); loading sizes from a config/env file without validating; misunderstanding that the size must be an exact power of two.

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/5a85434b086403ac. Report an issue: GitHub.