deepseek-ai/deepseek-harness · critical
web boot: window.__ModuleLoader__ bootstrap facade is missin
Error message
web boot: window.__ModuleLoader__ bootstrap facade is missing
What it means
AppWebEntry.run — the browser boot kernel of @deepseek-ai/dsh-client-web — requires the host page to install window.__ModuleLoader__ (the bootstrap facade that owns module creation and the boot manifest) before boot starts. If the global is undefined the kernel cannot even build the module system, so it aborts boot with this error and renders the failure on the boot page.
Source
Thrown at packages/client/web/src/boot.ts:51
* @param seams - Optional module transport replacement.
*/
constructor(container: HTMLElement, seams?: BootSeams) {
this.container = container
this.seams = seams
this.page = new BootPage(container)
}
/**
* Load and activate every client entry, then hand the mount point to the
* UI renderer. Plugin failures remain visible on the boot page.
* @returns Resolves after application mount or failure rendering.
*/
async run(): Promise<void> {
try {
const win = globalThis as DshWindow
const moduleLoader = win.__ModuleLoader__
if (moduleLoader === undefined) {
throw new Error('web boot: window.__ModuleLoader__ bootstrap facade is missing')
}
// A pre-injected transport (the worker preview page) owns bundle bytes;
// its loadBundle is the default and explicit seams still win. The global
// is `ClientTransportHooks`, owned by @deepseek-ai/dsh-client-connection;
// this structural slice reads one optional member without adding a
// package edge.
const transport = (globalThis as {
__DSH_TRANSPORT__?: { loadBundle?: ClientModuleCreateOptions['loadBundle'] }
}).__DSH_TRANSPORT__
this.modules = moduleLoader.create({
boot: win.__DSH_BOOT__,
staticModules: getStaticModules(),
...transport?.loadBundle === undefined ? {} : { loadBundle: transport.loadBundle },
...this.seams,
})
this.manifest = this.modules.manifest
const prefetching = this.prefetchImmediateTier()View on GitHub (pinned to b150a551b8)
Solutions
- Ensure the script that defines window.__ModuleLoader__ executes before the web boot bundle in the host page.
- Check the browser console/network tab for a failed load of that script (404, wrong MIME type, CSP block) and fix the serving path or policy.
- In jsdom tests, seed the global (or pass seams) in setup before invoking AppWebEntry.run.
- If the shell was refactored, grep the built shell output for __ModuleLoader__ to confirm the facade is still assigned early.
Example fix
<!-- before — boot kernel runs before the loader facade exists --> <script src="/assets/boot.js"></script> <script src="/assets/loader.js"></script> <!-- after — loader facade first, boot kernel second --> <script src="/assets/loader.js"></script> <script src="/assets/boot.js"></script>
Defensive patterns
Strategy: validation
Validate before calling
const win = globalThis as DshWindow
if (win.__ModuleLoader__ === undefined) {
// surface a setup error or seed the facade before boot; run() would abort
throw new Error('host page did not install the __ModuleLoader__ facade')
} Type guard
function hasModuleLoader(w: unknown): w is DshWindow {
return typeof (w as DshWindow).__ModuleLoader__ !== 'undefined'
} Try / catch
run() already catches every boot error and renders it on the boot page; callers awaiting run() should log the failure instead of rethrowing. In tests, assert the rendered failure text rather than wrapping run() in another try/catch.
Prevention
- Keep the facade-defining script first in the host page; add a CI check that the emitted HTML contains it.
- Seed window.__ModuleLoader__ in jsdom setup when testing AppWebEntry.
- Treat renaming __ModuleLoader__ as a breaking host-page change and update the shell template in the same commit.
When it happens
Trigger: Loading the web client bundle in a page where the script that defines window.__ModuleLoader__ never ran: omitted from the host HTML, loaded after the boot bundle, 404 or blocked by CSP. Also hit in jsdom tests that run AppWebEntry without seeding the global (the expectBootFailure helper exercises exactly this path).
Common situations: Custom host page assembled without the loader script tag; bundler/CDN misroute drops the bootstrap chunk; a refactor renames or removes the global; test setup forgets to seed window.__ModuleLoader__ before calling run().
Related errors
- ${binName}: profile bundle ${JSON.stringify(packageName)} de
- client-modules: window.__DSH_BOOT__ is missing or not an obj
- client-modules: boot manifest rev must be a string
- client-modules: HTML did not preload ${CLIENT_MODULES_ID}/cl
- client-modules: ${CLIENT_MODULES_ID}/client.js requested ext
AI-assisted analysis of deepseek-ai/deepseek-harness@b150a551b8 (2026-08-24).
Data as JSON: /api/errors/ea9c0f228dc22d0c.
Report an issue: GitHub.