{"record":{"id":"595d06163d307c4c","repo":"ionic-team/ionic-framework","slug":"framework-delegate-is-missing","errorCode":null,"errorMessage":"framework delegate is missing","messagePattern":"framework delegate is missing","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"core/src/utils/framework-delegate.ts","lineNumber":19,"sourceCode":"import type { ComponentRef, FrameworkDelegate } from '../interface';\n\nimport { componentOnReady } from './helpers';\n\n// TODO(FW-2832): types\n\nexport const attachComponent = async (\n  delegate: FrameworkDelegate | undefined,\n  container: Element,\n  component?: ComponentRef,\n  cssClasses?: string[],\n  componentProps?: { [key: string]: any },\n  inline?: boolean\n): Promise<HTMLElement> => {\n  if (delegate) {\n    return delegate.attachViewToDom(container, component, componentProps, cssClasses);\n  }\n  if (!inline && typeof component !== 'string' && !(component instanceof HTMLElement)) {\n    throw new Error('framework delegate is missing');\n  }\n\n  const el: any = typeof component === 'string' ? container.ownerDocument?.createElement(component) : component;\n\n  if (cssClasses) {\n    cssClasses.forEach((c) => el.classList.add(c));\n  }\n  if (componentProps) {\n    Object.assign(el, componentProps);\n  }\n\n  container.appendChild(el);\n\n  await new Promise((resolve) => componentOnReady(el, resolve));\n\n  return el;\n};\n","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/ionic-team/ionic-framework/blob/625f9c38ad8c5db8a6c12df5c1622a36da90f9e3/core/src/utils/framework-delegate.ts#L1-L37","documentation":"Thrown by attachComponent() in framework-delegate.ts when no FrameworkDelegate was supplied, the call is not inline, and the component argument is neither a tag string nor an existing HTMLElement. In that situation Ionic has no way to materialize the component (it would need a framework's compiler/change-detection), so it aborts rather than appending undefined.","triggerScenarios":"attachComponent is invoked with a component that is a class/component-reference object (not a string tag, not a DOM node) while delegate is undefined and inline is false. This is exactly what happens when a framework-less setup tries to mount a framework component, or when a delegate was expected but never wired (e.g. Angular DelegateController not provided, React/Vue bridge missing).","commonSituations":"Using ion-modal/ion-popover/ion-nav `component` property with a class reference in a vanilla or incorrectly-initialized project; SSR or test harness that doesn't register the framework delegate; migrating an app and forgetting to provide the Angular Delegate / React IonicReactDelegate / Vue delegate.","solutions":["Provide the correct framework delegate (Angular: pass the DelegateController/Delegate; React: ensure IonReactDelegate wraps the app; Vue: install the Ionic Vue plugin so the delegate is registered).","If you intend a vanilla setup, pass component as a tag string (e.g. 'ion-custom-page') or a pre-built HTMLElement instead of a class reference.","For overlays, prefer inline usage (place the content as children of ion-modal/ion-popover) so attachComponent takes the inline path.","Verify the framework integration package (@ionic/angular, @ionic/react, @ionic/vue) is installed and bootstrapped before presenting overlays/nav."],"exampleFix":"// before (vanilla, class reference, no delegate)\noverlay.component = MyPageClass;\nawait overlay.present(); // throws 'framework delegate is missing'\n\n// after (vanilla: pass an element or tag string)\noverlay.component = document.createElement('ion-custom-page');\nawait overlay.present();","handlingStrategy":"validation","validationCode":"function canAttachWithoutDelegate(component: unknown, inline: boolean): boolean {\n  return inline || typeof component === 'string' || component instanceof HTMLElement;\n}\nif (!delegate && !canAttachWithoutDelegate(component, inline)) {\n  // pass a tag string / HTMLElement, or supply a framework delegate\n}","typeGuard":"function isAttachableComponent(c: unknown): c is string | HTMLElement {\n  return typeof c === 'string' || c instanceof HTMLElement;\n}","tryCatchPattern":null,"preventionTips":["Always bootstrap the matching framework package (@ionic/angular/react/vue).","In vanilla code, pass component as a tag string or a pre-built HTMLElement.","Prefer inline overlay/nav content over class-reference components when delegate-less."],"tags":["overlays","delegate","framework-integration","nav","runtime"],"backgroundTag":null,"analyzedSha":"625f9c38ad8c5db8a6c12df5c1622a36da90f9e3","analyzedAt":"2026-08-12T16:00:25.413Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}