videojs/video.js · critical · Error

No Tech named '${titleTechName}' exists! '${titleTechName}'

Error message

No Tech named '${titleTechName}' exists! '${titleTechName}' should be registered using videojs.registerTech()'

What it means

When the player resolves a source to a tech name (defaulting to the source type, e.g. 'Html5'), it must find a registered Tech class via Tech.getTech(techName). If none is registered under that name (TitleCased or lowercased), playback cannot proceed and the error names the missing tech and the correct registration API.

Source

Thrown at src/js/player.js:1255

    });

    Object.assign(techOptions, this.options_[titleTechName]);
    Object.assign(techOptions, this.options_[camelTechName]);
    Object.assign(techOptions, this.options_[techName.toLowerCase()]);

    if (this.tag) {
      techOptions.tag = this.tag;
    }

    if (source && source.src === this.cache_.src && this.cache_.currentTime > 0) {
      techOptions.startTime = this.cache_.currentTime;
    }

    // Initialize tech instance
    const TechClass = Tech.getTech(techName);

    if (!TechClass) {
      throw new Error(`No Tech named '${titleTechName}' exists! '${titleTechName}' should be registered using videojs.registerTech()'`);
    }

    this.tech_ = new TechClass(techOptions);

    // player.triggerReady is always async, so don't need this to be async
    this.tech_.ready(Fn.bind_(this, this.handleTechReady_), true);

    textTrackConverter.jsonToTextTracks(this.textTracksJson_ || [], this.tech_);

    // Listen to all HTML5-defined events and trigger them on the player
    TECH_EVENTS_RETRIGGER.forEach((event) => {
      this.on(this.tech_, event, (e) => this[`handleTech${toTitleCase(event)}_`](e));
    });

    Object.keys(TECH_EVENTS_QUEUE).forEach((event) => {
      this.on(this.tech_, event, (eventObj) => {
        if (this.tech_.playbackRate() === 0 && this.tech_.seeking()) {
          this.queuedCallbacks_.push({

View on GitHub (pinned to c3a7e0e6d2)

Solutions

  1. Register the tech before playback: videojs.registerTech('MyTech', MyTech).
  2. For HLS/DASH, import the tech so it self-registers: import 'videojs-contrib-hls' / import '@videojs/http-streaming'.
  3. Ensure Html5 is included in custom builds (it is the base tech).
  4. Check the source.type spelling matches what the tech advertises.

Example fix

// before
player.src({ src: 'm.m3u8', type: 'application/x-mpegURL' }); // no HLS tech
// after
import 'videojs-http-streaming'; // registers itself
player.src({ src: 'm.m3u8', type: 'application/x-mpegURL' });
Defensive patterns

Strategy: validation

Validate before calling

function safeLoadTech(player, name, options) {
  if (!videojs.getTech(name) && !videojs.getTech(name.charAt(0).toUpperCase() + name.slice(1))) {
    throw new Error(`Tech '${name}' is not registered`);
  }
  return player.tech_.loadTech_(name, options);
}

Type guard

const isRegisteredTech = (name) =>
  Boolean(videojs.getTech(name));

Try / catch

try {
  player.src(source);
} catch (e) {
  if (/No Tech named/.test(e.message)) { showTechMissingUI(source); }
  else throw e;
}

Prevention

When it happens

Trigger: Loading a source whose type maps to a tech that was not registered (e.g. HLS source without videojs-http-streaming); calling player.loadTech('MyTech') without registerTech; custom build that omits Html5; tech name case mismatch.

Common situations: Forgetting to include the HLS/DASH tech plugin; bundler tree-shaking the tech's side-effect import; renaming a tech; using a Flash tech in builds where it was removed (v8).

Related errors


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