{"record":{"id":"635f9b215dba1189","repo":"videojs/video.js","slug":"texttrack-kind-is-required-but-was-not-provided","errorCode":null,"errorMessage":"TextTrack kind is required but was not provided","messagePattern":"TextTrack kind is required but was not provided","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/js/tech/tech.js","lineNumber":724,"sourceCode":"\n  /**\n   * Create and returns a remote {@link TextTrack} object.\n   *\n   * @param {string} kind\n   *        `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)\n   *\n   * @param {string} [label]\n   *        Label to identify the text track\n   *\n   * @param {string} [language]\n   *        Two letter language abbreviation\n   *\n   * @return {TextTrack}\n   *         The TextTrack that gets created.\n   */\n  addTextTrack(kind, label, language) {\n    if (!kind) {\n      throw new Error('TextTrack kind is required but was not provided');\n    }\n\n    return createTrackHelper(this, kind, label, language);\n  }\n\n  /**\n   * Create an emulated TextTrack for use by addRemoteTextTrack\n   *\n   * This is intended to be overridden by classes that inherit from\n   * Tech in order to create native or custom TextTracks.\n   *\n   * @param {Object} options\n   *        The object should contain the options to initialize the TextTrack with.\n   *\n   * @param {string} [options.kind]\n   *        `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata).\n   *\n   * @param {string} [options.label].","sourceCodeStart":706,"sourceCodeEnd":742,"githubUrl":"https://github.com/videojs/video.js/blob/c3a7e0e6d20cf5400c9afbee29965fe4dff393c2/src/js/tech/tech.js#L706-L742","documentation":"Thrown by Tech#addTextTrack(kind, label, language) when the first positional argument is falsy. The HTML5 TextTrack spec requires a 'kind', and video.js enforces it synchronously before delegating to createTrackHelper. Valid kinds are 'subtitles', 'captions', 'descriptions', 'chapters', and 'metadata'.","triggerScenarios":"Calling player.addTextTrack() / tech.addTextTrack() with no arguments, with undefined, null, or an empty string as the first argument. Also when a config-driven caller passes label as the first argument by positional confusion (e.g. addTextTrack('English','en')).","commonSituations":"Building subtitle/caption menus dynamically where 'kind' comes from user config or a data file that may omit it; refactoring a label-first API into the kind-first video.js API; SSR builds where the track list is constructed before kind is resolved.","solutions":["Pass a valid kind string as the first argument: 'subtitles', 'captions', 'descriptions', 'chapters', or 'metadata'.","Validate the config value is one of the five valid kinds before calling addTextTrack.","If kind is optional in your UI, default it to 'subtitles' explicitly."],"exampleFix":"// before\nplayer.addTextTrack(undefined, 'English', 'en');\n// after\nplayer.addTextTrack('subtitles', 'English', 'en');","handlingStrategy":"type-guard","validationCode":"const VALID_KINDS = ['subtitles', 'captions', 'descriptions', 'chapters', 'metadata'];\nfunction addTrackSafe(player, kind, label, language) {\n  if (!VALID_KINDS.includes(kind)) {\n    throw new TypeError(`kind must be one of ${VALID_KINDS.join(', ')}, got: ${kind}`);\n  }\n  return player.addTextTrack(kind, label, language);\n}","typeGuard":"function isTextTrackKind(kind) {\n  return typeof kind === 'string' && ['subtitles','captions','descriptions','chapters','metadata'].includes(kind);\n}","tryCatchPattern":"try {\n  player.addTextTrack(kind, label, language);\n} catch (err) {\n  if (/TextTrack kind is required/.test(err.message)) {\n    player.addTextTrack('subtitles', label, language);\n  } else { throw err; }\n}","preventionTips":["Always pass 'kind' as the first positional argument.","Validate config-derived kind values against the five valid kinds before calling addTextTrack.","Default optional kinds to 'subtitles' explicitly rather than leaving undefined."],"tags":["text-track","validation","api-misuse"],"backgroundTag":null,"analyzedSha":"c3a7e0e6d20cf5400c9afbee29965fe4dff393c2","analyzedAt":"2026-08-13T04:20:15.471Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}