{"record":{"id":"9f333f75375d2bf8","repo":"videojs/video.js","slug":"techs-must-have-a-static-canplaytype-method-on-the","errorCode":null,"errorMessage":"Techs must have a static canPlayType method on them","messagePattern":"Techs must have a static canPlayType method on them","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/js/tech/tech.js","lineNumber":1022,"sourceCode":"   * Registers a `Tech` into a shared list for videojs.\n   *\n   * @param {string} name\n   *        Name of the `Tech` to register.\n   *\n   * @param {Object} tech\n   *        The `Tech` class to register.\n   */\n  static registerTech(name, tech) {\n    if (!Tech.techs_) {\n      Tech.techs_ = {};\n    }\n\n    if (!Tech.isTech(tech)) {\n      throw new Error(`Tech ${name} must be a Tech`);\n    }\n\n    if (!Tech.canPlayType) {\n      throw new Error('Techs must have a static canPlayType method on them');\n    }\n    if (!Tech.canPlaySource) {\n      throw new Error('Techs must have a static canPlaySource method on them');\n    }\n\n    name = toTitleCase(name);\n\n    Tech.techs_[name] = tech;\n    Tech.techs_[toLowerCase(name)] = tech;\n    if (name !== 'Tech') {\n      // camel case the techName for use in techOrder\n      Tech.defaultTechOrder_.push(name);\n    }\n    return tech;\n  }\n\n  /**\n   * Get a `Tech` from the shared list by name.","sourceCodeStart":1004,"sourceCodeEnd":1040,"githubUrl":"https://github.com/videojs/video.js/blob/c3a7e0e6d20cf5400c9afbee29965fe4dff393c2/src/js/tech/tech.js#L1004-L1040","documentation":"Intended to ensure a registered tech exposes a static canPlayType method. NOTE: the guard checks 'Tech.canPlayType' (the base Tech class) rather than 'tech.canPlayType' (the argument being registered). The base class defines static canPlayType at src/js/tech/tech.js:968, so this check effectively always passes and is unreachable in normal use. To hit it you must delete or overwrite Tech.canPlayType before calling registerTech.","triggerScenarios":"Only fires if Tech.canPlayType on the base class has been deleted, monkeypatched to a falsy value, or never assigned (e.g. an aggressive test mock of the Tech class, or a fork that removed the base static method). Real custom techs inherit the method and never trigger it.","commonSituations":"Essentially unreachable in production. May surface in unit tests that stub the Tech class, or in a downstream fork that strips base-class statics during tree-shaking/minification.","solutions":["Do not delete or override Tech.canPlayType / Tech.canPlaySource on the base class.","If you actually need to validate a tech exposes canPlayType, check the tech argument directly: if (!tech.canPlayType).","Report the upstream check-vs-argument bug (Tech.canPlayType should be tech.canPlayType)."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"function registerTechSafe(name, tech) {\n  if (typeof tech.canPlayType !== 'function') {\n    throw new TypeError(`${name} must define a static canPlayType method`);\n  }\n  videojs.registerTech(name, tech);\n}","typeGuard":"function techHasCanPlayType(tech) {\n  return typeof tech.canPlayType === 'function';\n}","tryCatchPattern":null,"preventionTips":["Do not delete or monkeypatch Tech.canPlayType on the base class.","Validate the tech argument directly (tech.canPlayType) since the built-in guard checks the base class instead.","In tests, mock the tech argument, not the base Tech class statics."],"tags":["tech","registration","dead-code","upstream-bug"],"backgroundTag":null,"analyzedSha":"c3a7e0e6d20cf5400c9afbee29965fe4dff393c2","analyzedAt":"2026-08-13T04:20:15.471Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}