{"record":{"id":"0e032a9434dd2a20","repo":"dotnet/AspNetCore.Docs","slug":"this-type-template-option-must-consist-of-exa","errorCode":null,"errorMessage":"${this.type} `template` option must consist of exactly 1 top-level element!","messagePattern":"(.+?) `template` option must consist of exactly 1 top-level element!","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"aspnetcore/mvc/controllers/testing/samples/2.x/TestingControllersSample/src/TestingControllersSample/wwwroot/js/bootstrap.js","lineNumber":1690,"sourceCode":"      var o  = this.options\n  \n      title = $e.attr('data-original-title')\n        || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)\n  \n      return title\n    }\n  \n    Tooltip.prototype.getUID = function (prefix) {\n      do prefix += ~~(Math.random() * 1000000)\n      while (document.getElementById(prefix))\n      return prefix\n    }\n  \n    Tooltip.prototype.tip = function () {\n      if (!this.$tip) {\n        this.$tip = $(this.options.template)\n        if (this.$tip.length != 1) {\n          throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')\n        }\n      }\n      return this.$tip\n    }\n  \n    Tooltip.prototype.arrow = function () {\n      return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))\n    }\n  \n    Tooltip.prototype.enable = function () {\n      this.enabled = true\n    }\n  \n    Tooltip.prototype.disable = function () {\n      this.enabled = false\n    }\n  \n    Tooltip.prototype.toggleEnabled = function () {","sourceCodeStart":1672,"sourceCodeEnd":1708,"githubUrl":"https://github.com/dotnet/AspNetCore.Docs/blob/c67a80103a1a74db20784debd919c7fdda96c510/aspnetcore/mvc/controllers/testing/samples/2.x/TestingControllersSample/src/TestingControllersSample/wwwroot/js/bootstrap.js#L1672-L1708","documentation":"Bootstrap 3.3.7's Tooltip.prototype.tip() builds its DOM node by running the `template` option through jQuery's $(). It requires the result to contain exactly one top-level element (this.$tip.length === 1). Anything else — empty, multiple siblings, or a bare selector — is treated as a misconfiguration and throws on first show. The `${this.type}` prefix is the plugin name (\"tooltip\" or \"popover\"), since Popover extends Tooltip.","triggerScenarios":"Calling $('#el').tooltip({template: '...'}) or .popover({template: '...'}) where the string yields zero or 2+ top-level nodes; passing a CSS selector like '.my-tip' instead of HTML; an empty string; HTML with leading text siblings like 'x<div></div>'.","commonSituations":"Customizing tooltip markup; copying a template from another Bootstrap version whose default differs; bundler mangling the string; leaving a half-edited default template.","solutions":["Make the template a single rooted HTML element string, e.g. '<div class=\"tooltip\" role=\"tooltip\"><div class=\"tooltip-arrow\"></div><div class=\"tooltip-inner\"></div></div>'.","Do not pass a CSS selector as `template`; it is interpreted as HTML by jQuery and may match 0 or many nodes.","If overriding per-instance, validate the string has exactly one root before passing it.","If you don't need a custom template, remove the option entirely to use Bootstrap's built-in default."],"exampleFix":"// before\n$('#el').tooltip({ template: '<div class=\"tip\"></div><span class=\"extra\"></span>' });\n// after\n$('#el').tooltip({ template: '<div class=\"tip\" role=\"tooltip\"><div class=\"tooltip-inner\"></div></div>' });","handlingStrategy":"validation","validationCode":"// Validate a Bootstrap template string has exactly one top-level element before init.\nfunction isValidTooltipTemplate(tpl) {\n  if (typeof tpl !== 'string' || tpl.trim() === '') return false;\n  var nodes = $(tpl);\n  return nodes.length === 1 && nodes[0].nodeType === 1;\n}\nvar tpl = options && options.template;\nif (tpl && !isValidTooltipTemplate(tpl)) {\n  console.warn('Refusing to init tooltip: template is not a single top-level element');\n  delete options.template;\n}\n$('#el').tooltip(options);","typeGuard":"function isSingleElementTemplate(tpl) {\n  return typeof tpl === 'string' && $(tpl).length === 1;\n}","tryCatchPattern":"try {\n  $('#el').tooltip({ template: customTpl });\n} catch (e) {\n  if (/template.*1 top-level element/.test(e.message)) {\n    console.error('Bad tooltip template, falling back to default', customTpl);\n    $('#el').tooltip({}); // default template\n  } else { throw e; }\n}","preventionTips":["Always wrap template strings in a single root <div>; never pass selectors.","Keep per-instance templates in a shared, tested constant rather than inline literals.","Add a smoke-test that calls .tooltip('show') for each custom template at build time."],"tags":["bootstrap","tooltip","dom","template","configuration"],"backgroundTag":null,"analyzedSha":"c67a80103a1a74db20784debd919c7fdda96c510","analyzedAt":"2026-08-13T17:46:11.763Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}