{"record":{"id":"5a85434b086403ac","repo":"discordjs/discord.js","slug":"invalid-size-provided-size-must-be-one-of-a","errorCode":null,"errorMessage":"Invalid size provided: ${size}\nMust be one of: ${ALLOWED_SIZES.join(', ')}","messagePattern":"Invalid size provided: (.+?)\nMust be one of: (.+?)","errorType":"exception","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"packages/rest/src/lib/CDN.ts","lineNumber":393,"sourceCode":"\tprivate makeURL(\n\t\troute: string,\n\t\t{\n\t\t\tallowedExtensions = ALLOWED_EXTENSIONS,\n\t\t\tbase = this.cdn,\n\t\t\textension = 'webp',\n\t\t\tsize,\n\t\t\tanimated,\n\t\t}: Readonly<MakeURLOptions> = {},\n\t): string {\n\t\t// eslint-disable-next-line no-param-reassign\n\t\textension = String(extension).toLowerCase();\n\n\t\tif (!allowedExtensions.includes(extension)) {\n\t\t\tthrow new RangeError(`Invalid extension provided: ${extension}\\nMust be one of: ${allowedExtensions.join(', ')}`);\n\t\t}\n\n\t\tif (size && !ALLOWED_SIZES.includes(size)) {\n\t\t\tthrow new RangeError(`Invalid size provided: ${size}\\nMust be one of: ${ALLOWED_SIZES.join(', ')}`);\n\t\t}\n\n\t\tconst url = new URL(`${base}${route}.${extension}`);\n\n\t\tif (animated !== undefined) {\n\t\t\turl.searchParams.set('animated', String(animated));\n\t\t}\n\n\t\tif (size) {\n\t\t\turl.searchParams.set('size', String(size));\n\t\t}\n\n\t\treturn url.toString();\n\t}\n}\n","sourceCodeStart":375,"sourceCodeEnd":409,"githubUrl":"https://github.com/discordjs/discord.js/blob/a81ed8a306d37fdc746e26a634b6a42164ba2c8c/packages/rest/src/lib/CDN.ts#L375-L409","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Snap the size to the nearest allowed power of two: one of 16, 32, 64, 128, 256, 512, 1024, 2048, 4096.","Import ALLOWED_SIZES from @discordjs/rest and pick the closest allowed value programmatically before calling the URL builder.","Omit the `size` option entirely to get the asset's default (often 128px for avatars).","If the size comes from config or user input, validate it against ALLOWED_SIZES at load time and fail/normalize early."],"exampleFix":"// before\nconst url = user.displayAvatarURL({ size: 100 }); // RangeError\n// after\nimport { ALLOWED_SIZES } from '@discordjs/rest';\nconst size = ALLOWED_SIZES.reduce((a, b) => (Math.abs(b - 100) < Math.abs(a - 100) ? b : a));\nconst url = user.displayAvatarURL({ size }); // 128","handlingStrategy":"validation","validationCode":"import { ALLOWED_SIZES } from '@discordjs/rest';\nfunction nearestSize(wanted: number): ImageSize {\n  return ALLOWED_SIZES.reduce((a, b) => (Math.abs(b - wanted) < Math.abs(a - wanted) ? b : a));\n}","typeGuard":"const isImageSize = (v: number): v is ImageSize =>\n  [16, 32, 64, 128, 256, 512, 1024, 2048, 4096].includes(v);","tryCatchPattern":"try {\n  url = user.displayAvatarURL({ size });\n} catch (error) {\n  if (error instanceof RangeError && error.message.startsWith('Invalid size')) {\n    url = user.displayAvatarURL({ size: nearestSize(size) });\n  } else {\n    throw error;\n  }\n}","preventionTips":["Always snap arbitrary pixel dimensions to the nearest power-of-two in ALLOWED_SIZES before building URLs.","Type size inputs as ImageSize from discord-api-types so invalid literals fail at compile time.","Validate config/env-driven sizes once at startup instead of at every request.","Omit `size` when the default resolution is acceptable."],"tags":["validation","cdn","input-error","range-error"],"backgroundTag":"invalid-enum-value","analyzedSha":"a81ed8a306d37fdc746e26a634b6a42164ba2c8c","analyzedAt":"2026-08-30T04:07:22.193Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}