{"record":{"id":"730d81e5ee4c55c6","repo":"dotnet/AspNetCore.Docs","slug":"selector-option-must-be-specified-when-initializ","errorCode":null,"errorMessage":"`selector` option must be specified when initializing ${this.type} on the window.document object!","messagePattern":"`selector` option must be specified when initializing (.+?) on the window\\.document object!","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"aspnetcore/mvc/controllers/testing/samples/3.x/TestingControllersSample/src/TestingControllersSample/wwwroot/js/bootstrap.js","lineNumber":1314,"sourceCode":"      delay: 0,\n      html: false,\n      container: false,\n      viewport: {\n        selector: 'body',\n        padding: 0\n      }\n    }\n  \n    Tooltip.prototype.init = function (type, element, options) {\n      this.enabled   = true\n      this.type      = type\n      this.$element  = $(element)\n      this.options   = this.getOptions(options)\n      this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))\n      this.inState   = { click: false, hover: false, focus: false }\n  \n      if (this.$element[0] instanceof document.constructor && !this.options.selector) {\n        throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')\n      }\n  \n      var triggers = this.options.trigger.split(' ')\n  \n      for (var i = triggers.length; i--;) {\n        var trigger = triggers[i]\n  \n        if (trigger == 'click') {\n          this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))\n        } else if (trigger != 'manual') {\n          var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'\n          var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'\n  \n          this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))\n          this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))\n        }\n      }\n  ","sourceCodeStart":1296,"sourceCodeEnd":1332,"githubUrl":"https://github.com/dotnet/AspNetCore.Docs/blob/c67a80103a1a74db20784debd919c7fdda96c510/aspnetcore/mvc/controllers/testing/samples/3.x/TestingControllersSample/src/TestingControllersSample/wwwroot/js/bootstrap.js#L1296-L1332","documentation":"Bootstrap's Tooltip.init detects when the bound element is the document object itself (this.$element[0] instanceof document.constructor). Binding a tooltip/popover directly to document only makes sense as delegated initialization, which requires the `selector` option to tell Bootstrap which descendant elements actually carry the tooltip. Without `selector`, Bootstrap refuses — silently binding a single tooltip to document would never trigger correctly.","triggerScenarios":"$(document).tooltip({...}) or $(document).popover({...}) without a `selector` option; copy-pasting element-bound tooltip config onto document for global delegation.","commonSituations":"Trying to enable tooltips on dynamically injected HTML; converting per-element calls into one delegated call; misunderstanding Bootstrap's delegation API.","solutions":["Add a selector option: $(document).tooltip({ selector: '[data-toggle=\"tooltip\"]' });","Prefer binding delegation to a closer container than document (e.g. $('body')) for performance.","If you didn't mean delegation, bind to the actual elements: $('[data-toggle=\"tooltip\"]').tooltip()."],"exampleFix":"// before\n$(document).tooltip({ placement: 'top' }); // throws\n// after (delegated)\n$(document).tooltip({ selector: '[data-toggle=\"tooltip\"]', placement: 'top' });\n// or (direct)\n$('[data-toggle=\"tooltip\"]').tooltip({ placement: 'top' });","handlingStrategy":"validation","validationCode":"// Ensure a selector is supplied when delegating from document/body.\nfunction delegatedTooltip($host, opts) {\n  if (($host[0] === document || $host[0] === document.body) && !(opts && opts.selector)) {\n    throw new Error('Delegated tooltip on document requires opts.selector');\n  }\n  $host.tooltip(opts);\n}\ndelegatedTooltip($(document), { selector: '[data-toggle=\"tooltip\"]' });","typeGuard":"function isDelegationHost(el) { return el === document || el === document.body; }","tryCatchPattern":"try {\n  $(document).tooltip(opts);\n} catch (e) {\n  if (/`selector` option must be specified/.test(e.message)) {\n    console.error('Add selector for delegated tooltip init');\n    $(document).tooltip(Object.assign({ selector: '[data-toggle=\"tooltip\"]' }, opts));\n  } else { throw e; }\n}","preventionTips":["For dynamic content, always pass selector when binding to document/body.","Bind delegation to the nearest stable container, not document.","If not delegating, bind directly to the elements that carry data-toggle."],"tags":["bootstrap","tooltip","event-delegation","configuration"],"backgroundTag":null,"analyzedSha":"c67a80103a1a74db20784debd919c7fdda96c510","analyzedAt":"2026-08-13T17:46:11.763Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}