{"record":{"id":"711a553cf97f9fbe","repo":"videojs/video.js","slug":"techs-must-have-a-static-canplaysource-method-on-t","errorCode":null,"errorMessage":"Techs must have a static canPlaySource method on them","messagePattern":"Techs must have a static canPlaySource method on them","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/js/tech/tech.js","lineNumber":1025,"sourceCode":"   *        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.\n   *\n   * @param {string} name\n   *        `camelCase` or `TitleCase` name of the Tech to get","sourceCodeStart":1007,"sourceCodeEnd":1043,"githubUrl":"https://github.com/videojs/video.js/blob/c3a7e0e6d20cf5400c9afbee29965fe4dff393c2/src/js/tech/tech.js#L1007-L1043","documentation":"Intended to ensure a registered tech exposes a static canPlaySource method. NOTE: the guard checks 'Tech.canPlaySource' (the base Tech class) rather than 'tech.canPlaySource' (the argument). The base class defines static canPlaySource at src/js/tech/tech.js:981, so this check effectively always passes and is unreachable in normal use. To hit it you must delete or overwrite Tech.canPlaySource before calling registerTech.","triggerScenarios":"Only fires if Tech.canPlaySource on the base class has been deleted, monkeypatched to a falsy value, or never assigned (aggressive test mock, 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.","solutions":["Do not delete or override Tech.canPlayType / Tech.canPlaySource on the base class.","If you actually need to validate a tech exposes canPlaySource, check the tech argument directly: if (!tech.canPlaySource).","Report the upstream check-vs-argument bug (Tech.canPlaySource should be tech.canPlaySource)."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"function registerTechSafe(name, tech) {\n  if (typeof tech.canPlaySource !== 'function') {\n    throw new TypeError(`${name} must define a static canPlaySource method`);\n  }\n  videojs.registerTech(name, tech);\n}","typeGuard":"function techHasCanPlaySource(tech) {\n  return typeof tech.canPlaySource === 'function';\n}","tryCatchPattern":null,"preventionTips":["Do not delete or monkeypatch Tech.canPlaySource on the base class.","Validate the tech argument directly (tech.canPlaySource) 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"}