{"record":{"id":"825a672e4a51ad64","repo":"twbs/bootstrap","slug":"name-touppercase-option-reference-provided","errorCode":null,"errorMessage":"${NAME.toUpperCase()}: Option \"reference\" provided type \"object\" without a required \"getBoundingClientRect\" method.","messagePattern":"(.+?): Option \"reference\" provided type \"object\" without a required \"getBoundingClientRect\" method\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"js/src/dropdown.js","lineNumber":219,"sourceCode":"    if (this._popper) {\n      this._popper.destroy()\n    }\n\n    this._menu.classList.remove(CLASS_NAME_SHOW)\n    this._element.classList.remove(CLASS_NAME_SHOW)\n    this._element.setAttribute('aria-expanded', 'false')\n    Manipulator.removeDataAttribute(this._menu, 'popper')\n    EventHandler.trigger(this._element, EVENT_HIDDEN, relatedTarget)\n  }\n\n  _getConfig(config) {\n    config = super._getConfig(config)\n\n    if (typeof config.reference === 'object' && !isElement(config.reference) &&\n      typeof config.reference.getBoundingClientRect !== 'function'\n    ) {\n      // Popper virtual elements require a getBoundingClientRect method\n      throw new TypeError(`${NAME.toUpperCase()}: Option \"reference\" provided type \"object\" without a required \"getBoundingClientRect\" method.`)\n    }\n\n    return config\n  }\n\n  _createPopper() {\n    if (typeof Popper === 'undefined') {\n      throw new TypeError('Bootstrap\\'s dropdowns require Popper (https://popper.js.org/docs/v2/)')\n    }\n\n    let referenceElement = this._element\n\n    if (this._config.reference === 'parent') {\n      referenceElement = this._parent\n    } else if (isElement(this._config.reference)) {\n      referenceElement = getElement(this._config.reference)\n    } else if (typeof this._config.reference === 'object') {\n      referenceElement = this._config.reference","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/twbs/bootstrap/blob/6177d5f8497f2c08f9874f5221fd17ce5acd2ad7/js/src/dropdown.js#L201-L237","documentation":"Dropdown positions its menu with Popper, and the 'reference' option accepts 'toggle' (default), 'parent', a DOM element, or a Popper virtual element. _getConfig (dropdown.js:212) rejects objects that are neither elements nor expose a getBoundingClientRect method, because Popper needs that method to compute the menu position. The check runs on every Dropdown construction, including data-bs-toggle clicks that carry a programmatic config.","triggerScenarios":"new bootstrap.Dropdown(btn, { reference: $('.ref') }) — a jQuery collection is a plain object without getBoundingClientRect; { reference: { top: 0, left: 0 } }; { reference: window } or document; passing a React ref object ({ current: el }) or Vue template ref instead of ref.current / ref.value.","commonSituations":"jQuery-era code passing collections instead of single elements; framework wrappers (React/Vue) leaking ref objects into config; building custom virtual anchors for dropdowns attached to canvas, SVG or table cells; mixing up the 'parent' string with an object.","solutions":["Pass a real DOM element: document.querySelector('#ref') or $('.ref')[0].","Unwrap framework refs — React: ref.current, Vue 3: ref.value.","For a virtual anchor, provide the required method: { getBoundingClientRect: () => target.getBoundingClientRect() }.","When the reference is the adjacent parent, just use reference: 'parent'."],"exampleFix":"// before\nnew bootstrap.Dropdown(btn, { reference: $('#menuRef') })\n// DROPDOWN: Option \"reference\" provided type \"object\" without a required \"getBoundingClientRect\" method.\n\n// after — DOM element\nnew bootstrap.Dropdown(btn, { reference: document.querySelector('#menuRef') })\n\n// after — Popper virtual element\nnew bootstrap.Dropdown(btn, {\n  reference: { getBoundingClientRect: () => anchorEl.getBoundingClientRect() }\n})","handlingStrategy":"validation","validationCode":"function isDropdownReference(ref) {\n  if (typeof ref === 'string') return ref === 'toggle' || ref === 'parent'\n  if (ref instanceof Element) return true\n  return typeof ref?.getBoundingClientRect === 'function' // Popper virtual element\n}\n\nif (!isDropdownReference(options.reference)) {\n  throw new TypeError('reference must be \"toggle\"|\"parent\", a DOM element, or a virtual element with getBoundingClientRect')\n}\nnew bootstrap.Dropdown(btn, options)","typeGuard":"function isVirtualElement(ref: unknown): ref is { getBoundingClientRect: () => DOMRect } {\n  return typeof ref === 'object' && ref !== null &&\n    !(ref instanceof Element) &&\n    typeof (ref as { getBoundingClientRect?: unknown }).getBoundingClientRect === 'function'\n}","tryCatchPattern":"try {\n  new bootstrap.Dropdown(btn, options)\n} catch (err) {\n  if (err instanceof TypeError && /Option \"reference\"/.test(err.message)) {\n    // fall back to the default reference ('toggle') and log the bad value's shape\n    new bootstrap.Dropdown(btn)\n  } else {\n    throw err\n  }\n}","preventionTips":["Unwrap before passing: jQuery $('.x')[0], React ref.current, Vue ref.value.","Model virtual anchors on Popper's virtual-element docs — getBoundingClientRect is the one required method.","Prefer reference: 'parent' or a selector-resolved element when a real anchor exists.","Add unit tests asserting the reference's shape at the wrapper boundary."],"tags":["bootstrap","dropdown","popper","reference","config-validation","typeerror"],"backgroundTag":"invalid-option-type","analyzedSha":"6177d5f8497f2c08f9874f5221fd17ce5acd2ad7","analyzedAt":"2026-08-22T03:20:03.375Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}