quasarframework/quasar · error · TypeError

Expected 3 numbers below 256 (and optionally one below 100)

Error message

Expected 3 numbers below 256 (and optionally one below 100)

What it means

Quasar's rgbToHex() converts r/g/b (and optional alpha percent) to a hex color string. It rounds each channel first, then throws a TypeError if any channel exceeds 255 or an alpha value exceeds 100. The error indicates the numeric color inputs are out of the valid RGB/alpha-percent ranges.

Source

Thrown at ui/src/utils/colors/colors.js:11

const reRGBA = /^rgb(a)?\((\d{1,3}),(\d{1,3}),(\d{1,3}),?([01]?\.?\d*?)?\)$/

export function rgbToHex({ r, g, b, a }) {
  const alpha = a !== void 0

  r = Math.round(r)
  g = Math.round(g)
  b = Math.round(b)

  if (r > 255 || g > 255 || b > 255 || (alpha && a > 100)) {
    throw new TypeError(
      'Expected 3 numbers below 256 (and optionally one below 100)'
    )
  }

  a = alpha
    ? (Math.round((255 * a) / 100) | (1 << 8)).toString(16).slice(1)
    : ''

  return '#' + (b | (g << 8) | (r << 16) | (1 << 24)).toString(16).slice(1) + a
}

export function rgbToString({ r, g, b, a }) {
  return `rgb${a !== void 0 ? 'a' : ''}(${r},${g},${b}${a !== void 0 ? ',' + a / 100 : ''})`
}

export function hexToRgb(hex) {
  if (typeof hex !== 'string') {
    throw new TypeError('Expected a string')

View on GitHub (pinned to 4841521b5f)

Solutions

  1. Clamp channels with Math.min(255, value) and alpha with Math.min(100, value) before calling rgbToHex
  2. Verify alpha is a 0–100 percent number, not a 0–1 fraction or a raw 8-bit alpha
  3. Check upstream color math (blend/changeAlpha inputs) for sign/range errors producing >255
  4. Validate user-supplied color numbers at the UI boundary before conversion

Example fix

// before
const hex = rgbToHex(r, g, b, a)
// after
const hex = rgbToHex(Math.min(255, Math.round(r)), Math.min(255, Math.round(g)), Math.min(255, Math.round(b)), Math.min(100, a))
Defensive patterns

Strategy: validation

Validate before calling

function canConvertToHex(r, g, b, a) {
  const ok = [r, g, b].every(n => Number.isFinite(n) && Math.round(n) <= 255 && Math.round(n) >= 0)
  const alphaOk = a === void 0 || (Number.isFinite(a) && a <= 100)
  return ok && alphaOk
}
if (!canConvertToHex(r, g, b, a)) clamp before calling rgbToHex

Type guard

function isRgbChannel(v) {
  return typeof v === 'number' && Number.isFinite(v) && v >= 0 && v <= 255
}
function isAlphaPercent(v) {
  return v === void 0 || (typeof v === 'number' && v >= 0 && v <= 100)
}

Try / catch

try {
  hex = rgbToHex(r, g, b, a)
} catch (err) {
  if (err.message.startsWith('Expected 3 numbers')) {
    hex = rgbToHex(Math.min(255, r), Math.min(255, g), Math.min(255, b), Math.min(100, a))
  } else {
    throw err
  }
}

Prevention

When it happens

Trigger: rgbToHex(300, 0, 0), rgbToHex(0, 0, 0, 150) (alpha percent > 100), or any caller (updateModel, parseModel, blend, changeAlpha, getPaletteColor pipeline) that receives computed channel values above 255 or alpha above 100.

Common situations: Color math done manually without clamping (blending, brightening) pushing channels over 255; parsing user input or CSV/design tokens where a value is 256–999; passing alpha as 0–1 fraction when the function expects 0–100 percent (e.g. 150 instead of 1.5 or 100).

Related errors


AI-assisted analysis of quasarframework/quasar@4841521b5f (2026-08-30). Data as JSON: /api/errors/cae75738410feafc. Report an issue: GitHub.