{"record":{"id":"e48aae67a000ab08","repo":"deepseek-ai/deepseek-harness","slug":"client-modules-window-dsh-boot-is-missing-or","errorCode":null,"errorMessage":"client-modules: window.__DSH_BOOT__ is missing or not an object","messagePattern":"client-modules: window\\.__DSH_BOOT__ is missing or not an object","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"packages/client/modules/src/client/manifest.ts","lineNumber":149,"sourceCode":" * require path and graph composition normalize here, which is what lets each\n * importing package request the subpath its own code imports.\n * @param spec - module specifier as a bundle requires it or a declaration spells it.\n * @returns the specifier with a trailing `/client` removed.\n */\nexport function stripClientSuffix(spec: string): string {\n  return spec.endsWith('/client') ? spec.slice(0, -'/client'.length) : spec\n}\n\n/**\n * Parse `window.__DSH_BOOT__` into the two consumer views. Wire boundary:\n * a missing or malformed graph throws (the shell shows the loud failure —\n * a page without a valid manifest cannot boot anything).\n * @param wire - the raw `window.__DSH_BOOT__` value.\n * @returns the manifest with optional plugin-view fields normalized.\n */\nexport function parseBootManifest(wire: unknown): BootManifest {\n  if (typeof wire !== 'object' || wire === null) {\n    throw new Error('client-modules: window.__DSH_BOOT__ is missing or not an object')\n  }\n  const graph = wire as Record<string, unknown>\n  if (typeof graph.rev !== 'string') {\n    throw new Error('client-modules: boot manifest rev must be a string')\n  }\n  if (!Array.isArray(graph.entries)) {\n    throw new Error('client-modules: boot manifest entries must be an array')\n  }\n  const modules: BootModuleRow[] = []\n  const plugins: BootPluginRow[] = []\n  for (const value of graph.entries as unknown[]) {\n    if (typeof value !== 'object' || value === null) {\n      throw new Error('client-modules: boot manifest entry is not an object')\n    }\n    const row = value as Record<string, unknown>\n    const where = typeof row.id === 'string' ? `\"${row.id}\"` : JSON.stringify(row)\n    if (typeof row.id !== 'string' || typeof row.url !== 'string' || typeof row.rev !== 'string') {\n      throw new Error(`client-modules: boot manifest entry ${where} must carry string id/url/rev`)","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/deepseek-ai/deepseek-harness/blob/b150a551b8d465e31e418e1b2eaf5e79bbb7d28e/packages/client/modules/src/client/manifest.ts#L131-L167","documentation":"The dsh web host injects the composed module graph into the page as window.__DSH_BOOT__ before the client module system starts; parseBootManifest enforces that wire boundary and throws when the value is missing or not an object. The built apps/web Vite shell is not a standalone application — only dsh web performs the injection — so a page served any other way fails here, and the shell shows the loud failure because a page without a valid manifest cannot boot anything.","triggerScenarios":"Opening the built frontend index.html directly from disk, via vite dev / vite preview, or behind a plain static server; or a host-side inline injection script that failed (CSP or extension blocking) before assigning the global.","commonSituations":"Frontend development opening the Vite dev server instead of the dsh-served URL; deploying dist/ behind nginx standalone; strict CSP stripping the inline boot script.","solutions":["Open the GUI at the URL dsh web prints (loopback or declared authority) — the injection happens only there","If developing the shell, keep dev rebuild tooling running but still load the page through the running dsh web server","On a dsh-served URL that still fails, check for a blocked inline boot script (CSP, extensions)"],"exampleFix":"// before\nconst manifest = parseBootManifest((window as any).__DSH_BOOT__)\n\n// after\nconst wire = (window as { __DSH_BOOT__?: unknown }).__DSH_BOOT__\nif (typeof wire !== 'object' || wire === null) {\n  throw new Error('serve this page via dsh web; window.__DSH_BOOT__ is host-injected')\n}\nconst manifest = parseBootManifest(wire)","handlingStrategy":"type-guard","validationCode":"const wire = (window as { __DSH_BOOT__?: unknown }).__DSH_BOOT__\nif (typeof wire !== 'object' || wire === null) {\n  showFatalError('open this page through the dsh web URL — the host injects window.__DSH_BOOT__')\n}","typeGuard":"function hasBootManifest(w: Window & { __DSH_BOOT__?: unknown }): w is Window & { __DSH_BOOT__: object } {\n  return typeof w.__DSH_BOOT__ === 'object' && w.__DSH_BOOT__ !== null\n}","tryCatchPattern":null,"preventionTips":["Never deploy or preview dist/ standalone; the shell requires host injection","Enter only through the dsh web URL","In e2e, drive the real served page, not a static copy"],"tags":["bootstrap","browser","manifest","web","runtime"],"backgroundTag":"missing-boot-manifest","analyzedSha":"b150a551b8d465e31e418e1b2eaf5e79bbb7d28e","analyzedAt":"2026-08-24T18:12:29.105Z","schemaVersion":2},"datasetVersion":"2026-08-24T22:17:12.610Z"}