deepseek-ai/deepseek-harness · error

client-modules: boot manifest rev must be a string

Error message

client-modules: boot manifest rev must be a string

What it means

The boot graph's rev is the consistency anchor over the whole module graph (content and bundle hashes). parseBootManifest requires it to be a string; a numeric, null, or absent rev means the graph is malformed or was produced by an incompatible host, and the parse refuses it at the wire boundary before any module loads.

Source

Thrown at packages/client/modules/src/client/manifest.ts:153

 */
export function stripClientSuffix(spec: string): string {
  return spec.endsWith('/client') ? spec.slice(0, -'/client'.length) : spec
}

/**
 * Parse `window.__DSH_BOOT__` into the two consumer views. Wire boundary:
 * a missing or malformed graph throws (the shell shows the loud failure —
 * a page without a valid manifest cannot boot anything).
 * @param wire - the raw `window.__DSH_BOOT__` value.
 * @returns the manifest with optional plugin-view fields normalized.
 */
export function parseBootManifest(wire: unknown): BootManifest {
  if (typeof wire !== 'object' || wire === null) {
    throw new Error('client-modules: window.__DSH_BOOT__ is missing or not an object')
  }
  const graph = wire as Record<string, unknown>
  if (typeof graph.rev !== 'string') {
    throw new Error('client-modules: boot manifest rev must be a string')
  }
  if (!Array.isArray(graph.entries)) {
    throw new Error('client-modules: boot manifest entries must be an array')
  }
  const modules: BootModuleRow[] = []
  const plugins: BootPluginRow[] = []
  for (const value of graph.entries as unknown[]) {
    if (typeof value !== 'object' || value === null) {
      throw new Error('client-modules: boot manifest entry is not an object')
    }
    const row = value as Record<string, unknown>
    const where = typeof row.id === 'string' ? `"${row.id}"` : JSON.stringify(row)
    if (typeof row.id !== 'string' || typeof row.url !== 'string' || typeof row.rev !== 'string') {
      throw new Error(`client-modules: boot manifest entry ${where} must carry string id/url/rev`)
    }
    const subject = `boot manifest entry ${where}`
    const inject = optionalStringArray(subject, 'inject', row.inject)
    const external = optionalStringArray(subject, 'external', row.external)

View on GitHub (pinned to b150a551b8)

Solutions

  1. Let the host generate the graph: restart dsh web (and pnpm --filter <pkg> bundle after client-plugin changes)
  2. If you fabricate the wire yourself (fixtures, custom hosts), emit rev as a string
  3. Use host and frontend from the same checkout/build so the wire shape matches

Example fix

// before (fixture/custom host)
window.__DSH_BOOT__ = { rev: 1724500000000, entries: [...] }

// after
window.__DSH_BOOT__ = { rev: '1724500000000', entries: [...] }
Defensive patterns

Strategy: type-guard

Validate before calling

const wire = (window as { __DSH_BOOT__?: unknown }).__DSH_BOOT__
if (typeof wire === 'object' && wire !== null && typeof (wire as { rev?: unknown }).rev !== 'string') {
  showFatalError('stale boot graph — rebuild client bundles and restart dsh web')
}

Type guard

function hasStringRev(wire: object): wire is object & { rev: string } {
  return typeof (wire as { rev?: unknown }).rev === 'string'
}

Prevention

When it happens

Trigger: window.__DSH_BOOT__ exists as an object but its rev is a number, null, or missing — a custom injection script, a stale host/frontend mix from different builds, or a hand-crafted test fixture.

Common situations: A test or custom host fabricating the graph with rev: Date.now(); mixing an old dsh binary with a newer frontend that changed the wire; manual edits of the injected global while debugging.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of deepseek-ai/deepseek-harness@b150a551b8 (2026-08-24). Data as JSON: /api/errors/7b9597fe4f866d43. Report an issue: GitHub.