Budibase/budibase · error
mountBudibaseApp requires a target HTMLElement
Error message
mountBudibaseApp requires a target HTMLElement
What it means
mountBudibaseApp mounts a Budibase app into a DOM element. Its first validation requires a truthy target that is an instance of HTMLElement; anything else (null, undefined, a selector string, a non-element object) is rejected with this error before any app loading begins.
Source
Thrown at packages/client/src/index.ts:321
if (!app) {
app = mount(ClientApp, {
target,
})
}
}
// Attach to window so the HTML template can call this when it loads
window.loadBudibase = loadBudibase
export const mountBudibaseApp = async ({
target,
appUrl,
appId,
initialPath,
onNavigate,
}: MountBudibaseAppOptions) => {
if (!target || !(target instanceof HTMLElement)) {
throw new Error("mountBudibaseApp requires a target HTMLElement")
}
const appPath = normalizeAppPath(appUrl)
const appHash = getHash(appUrl)
if (!appPath) {
throw new Error("mountBudibaseApp requires a valid appUrl")
}
const resolvedAppId = appId || (await resolveAppIdFromPath(appPath))
window["##BUDIBASE_APP_ID##"] = resolvedAppId
window["##BUDIBASE_EMBED_LOCATION##"] = appPath
const resolvedInitialPath = initialPath
? normalizeRoutePath(initialPath)
: appHash
? normalizeRoutePath(appHash.replace(/^#/, ""))
: undefinedView on GitHub (pinned to a81a902e9a)
Solutions
- Pass an actual DOM element: document.getElementById("root") or equivalent, and confirm it is non-null
- Call mountBudibaseApp after the DOM is ready (script at end of body, defer, or DOMContentLoaded listener)
- If using a selector, resolve it first: document.querySelector("#root")
Example fix
// before
mountBudibaseApp({ target: "#root", appUrl: "/my-app" })
// after
const el = document.getElementById("root")
mountBudibaseApp({ target: el, appUrl: "/my-app" }) Defensive patterns
Strategy: type-guard
Validate before calling
const el = document.getElementById("root")
if (!el || !(el instanceof HTMLElement)) {
throw new Error("Mount target not found or not an HTMLElement")
}
mountBudibaseApp({ target: el, appUrl }) Type guard
const isMountTarget = (t: unknown): t is HTMLElement => t instanceof HTMLElement
Try / catch
try {
await mountBudibaseApp({ target: getTarget(), appUrl })
} catch (err) {
if ((err as Error).message.includes("requires a target HTMLElement")) {
// resolve element after DOM ready and retry once
} else throw err
} Prevention
- Wait for DOMContentLoaded (or place script with defer) before mounting
- Pass the DOM node itself, never a selector string or framework ref object
- Assert the container element exists in dev to fail fast
When it happens
Trigger: Calling mountBudibaseApp with target omitted, null, a CSS selector string like "#root", or a non-HTMLElement object (e.g. a jQuery wrapper or the document).
Common situations: Calling before DOMContentLoaded so getElementById returns null; passing a query selector string instead of the element; querying the wrong container id; framework code passing a ref object rather than the DOM node.
Related errors
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/6b100f0f24dae27d.
Report an issue: GitHub.