videojs/video.js · error · Error

Invalid color code provided, ' + color + '; must be formatte

Error message

Invalid color code provided, ' + color + '; must be formatted as e.g. #f0e or #f604e2.

What it means

Thrown by constructColor(color, opacity) when the color string is not exactly 4 characters ('#rgb') or 7 characters ('#rrggbb'). constructColor converts a hex color plus an opacity into an rgba() string for VTT cue styling. Named colors, rgb()/hsl() notation, 8-digit alpha hex, and missing/malformed values are all rejected.

Source

Thrown at src/js/tracks/text-track-display.js:49

 *        Hex number for color, like #f0e or #f604e2.
 *
 * @param {number} opacity
 *        Value for opacity, 0.0 - 1.0.
 *
 * @return {string}
 *         The rgba color that was created, like 'rgba(255, 0, 0, 0.3)'.
 */
export function constructColor(color, opacity) {
  let hex;

  if (color.length === 4) {
    // color looks like "#f0e"
    hex = color[1] + color[1] + color[2] + color[2] + color[3] + color[3];
  } else if (color.length === 7) {
    // color looks like "#f604e2"
    hex = color.slice(1);
  } else {
    throw new Error('Invalid color code provided, ' + color + '; must be formatted as e.g. #f0e or #f604e2.');
  }
  return 'rgba(' +
    parseInt(hex.slice(0, 2), 16) + ',' +
    parseInt(hex.slice(2, 4), 16) + ',' +
    parseInt(hex.slice(4, 6), 16) + ',' +
    opacity + ')';
}

/**
 * Try to update the style of a DOM element. Some style changes will throw an error,
 * particularly in IE8. Those should be noops.
 *
 * @param {Element} el
 *        The DOM element to be styled.
 *
 * @param {string} style
 *        The CSS property on the element that should be styled.
 *

View on GitHub (pinned to c3a7e0e6d2)

Solutions

  1. Normalize the color to 3-digit or 6-digit hex before passing (strip alpha, convert named/rgb/hsl via a color library).
  2. Use the separate opacity parameter for alpha, not 8-digit hex.
  3. Validate against /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/ before calling.

Example fix

// before
constructColor('#ff0000ff', 0.5);
// after
constructColor('#ff0000', 0.5);
Defensive patterns

Strategy: validation

Validate before calling

const HEX = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
function safeConstructColor(color, opacity) {
  if (!HEX.test(color)) {
    throw new TypeError(`color must be #rgb or #rrggbb, got: ${color}`);
  }
  return videojs.constructColor(color, opacity);
}

Type guard

function isValidHexColor(c) {
  return typeof c === 'string' && /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(c);
}

Try / catch

try {
  style.color = videojs.constructColor(color, opacity);
} catch (err) {
  if (/Invalid color code/.test(err.message)) {
    style.color = videojs.constructColor('#fff', opacity);
  } else { throw err; }
}

Prevention

When it happens

Trigger: Calling constructColor directly with a bad format, or indirectly through text-track-display when overrides.color / overrides.backgroundColor / overrides.windowColor is a named color ('red'), 3/6-digit hex with extra chars, 8-digit hex ('#ff0000ff'), rgb()/hsl(), or a CSS variable value. These overrides originate from VTT cue 'style' settings or from player text-track-format options.

Common situations: Feeding caption colors from a design-system palette that uses 8-digit hex or named colors; reading color values from CSS custom properties or user input without normalization; trying to encode alpha in the hex instead of the separate opacity parameter.

Related errors


AI-assisted analysis of videojs/video.js@c3a7e0e6d2 (2026-08-13). Data as JSON: /api/errors/c8c72a008681d546. Report an issue: GitHub.