{"record":{"id":"68b60d8b980f99cc","repo":"dotnet/AspNetCore.Docs","slug":"this-type-template-option-must-consist-of-exa-68b60d","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/views/tag-helpers/th-components/samples/RazorPagesSample/wwwroot/lib/bootstrap/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/views/tag-helpers/th-components/samples/RazorPagesSample/wwwroot/lib/bootstrap/js/bootstrap.js#L1672-L1708","documentation":"Bootstrap 3's `Tooltip.tip()` wraps the `template` option in jQuery and throws if the result has `length != 1`. A tooltip/popover needs exactly one root element to position; zero (empty/invalid markup) or multiple roots are rejected.","triggerScenarios":"Setting a custom `template` option whose HTML has no top-level element (e.g. plain text) or more than one top-level element (e.g. two sibling divs). The check fires the first time the tooltip element is created.","commonSituations":"Custom template missing the outer wrapper div; template string has leading text nodes before the root; copy-paste from a partial template that was split across lines; malformed HTML that jQuery parses into multiple fragments.","solutions":["Wrap the template in a single root element matching the expected structure: `<div class=\"tooltip\" role=\"tooltip\">...</div>`.","Use the Bootstrap default template as a base and only edit inner HTML.","Validate the template parses to one element before passing it: a quick check with `$(tpl).length === 1`."],"exampleFix":"// before\ntemplate: '<div class=\"tooltip-arrow\"></div><div class=\"tooltip-inner\"></div>'\n\n// after\ntemplate: '<div class=\"tooltip\" role=\"tooltip\"><div class=\"tooltip-arrow\"></div><div class=\"tooltip-inner\"></div></div>'","handlingStrategy":"validation","validationCode":"function makeTooltip($elem, template) {\n  if ($(template).length !== 1) {\n    throw new Error('Tooltip template must have exactly one root element');\n  }\n  $elem.tooltip({ template: template });\n}","typeGuard":"function isSingleRootTemplate(template) {\n  return $(template).length === 1;\n}","tryCatchPattern":"try {\n  $el.tooltip({ template: tpl });\n} catch (e) {\n  if (/template/.test(e.message)) {\n    $el.tooltip(); // fall back to default template\n  } else throw e;\n}","preventionTips":["Start from Bootstrap's default template and edit inner HTML only.","Unit-test custom templates produce exactly one root node.","Validate templates in your config validator before applying."],"tags":["bootstrap","tooltip","template","configuration"],"backgroundTag":null,"analyzedSha":"c67a80103a1a74db20784debd919c7fdda96c510","analyzedAt":"2026-08-13T17:46:11.763Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}