deepseek-ai/deepseek-harness · critical

client-modules: ${CLIENT_MODULES_ID}/client.js did not expor

Error message

client-modules: ${CLIENT_MODULES_ID}/client.js did not export the bootstrap module face

What it means

After the preloaded bootstrap bundle's factory runs, its exports must be an object exposing both createClientModuleSystem and apply functions — the bootstrap module face the HTML queue protocol depends on. This error means the script that registered under id '@deepseek-ai/dsh-client-modules' executed and returned something else: a wrong, stale, or foreign artifact is being served at the preload URL, or the bundle was built against a different protocol version.

Source

Thrown at packages/client/modules/src/index.ts:259

export function bootInjections(graph: WebBootGraph): IndexInjection[] {
  const bootstrapId = JSON.stringify(CLIENT_MODULES_ID)
  const queue = `(()=>{
const pendingQueue=[]
window.__ModuleLoader__={
  mode:"queue",
  pendingQueue,
  load(registration){pendingQueue.push(registration)},
  create(options){
    if(this.mode!=="queue")throw new Error("client-modules: window.__ModuleLoader__.create called after module-system boot")
    const index=pendingQueue.findIndex(registration=>registration.id===${bootstrapId})
    const registration=pendingQueue[index]
    if(registration===undefined)throw new Error("client-modules: HTML did not preload ${CLIENT_MODULES_ID}/client.js")
    pendingQueue.splice(index,1)
    const exports=registration.factory(specifier=>{
      throw new Error('client-modules: ${CLIENT_MODULES_ID}/client.js requested external "'+specifier+'" before the module system existed')
    })
    if(typeof exports!=="object"||exports===null||typeof exports.createClientModuleSystem!=="function"||typeof exports.apply!=="function"){
      throw new Error("client-modules: ${CLIENT_MODULES_ID}/client.js did not export the bootstrap module face")
    }
    return exports.createClientModuleSystem(this,{id:registration.id,exports},options)
  }
}
})()`
  const preload = PARSER_PRELOAD_IDS.map(id => graph.entries.find(entry => entry.id === id))
    .filter((entry): entry is WebBootEntry => entry !== undefined)
    .map((entry): IndexInjection => ({ kind: 'script-src', placement: 'head', src: entry.url }))
  return [
    { kind: 'script', placement: 'head', text: queue },
    ...preload,
    { kind: 'global', name: '__DSH_BOOT__', value: graph },
  ]
}

/**
 * The web plugin table service: incremental `dsh.client` scan + wire composition
 * + bundle route + index injection rows. Construction runs the activation scan

View on GitHub (pinned to b150a551b8)

Solutions

  1. Run a full `pnpm run build` so HTML protocol and bundles come from the same build, then hard-reload.
  2. Fetch the preload URL and check the response is JavaScript and contains 'createClientModuleSystem'; if not, find what actually serves that path (static dir, proxy, service worker) and remove it.
  3. Check @deepseek-ai/dsh-client-modules package.json exports["./client"] still maps to the real bundle output (lib/client.js).
  4. Unregister service workers and clear cache in dev; keep the ?rev= cache-buster intact so stale bundles cannot survive a graph change.

Example fix

# before — stale artifact pinned by a copied static dir
cp -r old-dist/client.js static/plugins/@deepseek-ai/dsh-client-modules/

# after — the registry's own /plugins route serves the bundle it composed
curl 'http://localhost:3000/plugins/@deepseek-ai/dsh-client-modules/client.js?rev=<graph-rev>' | grep -c createClientModuleSystem
# expect: 1
Defensive patterns

Strategy: validation

Validate before calling

// pre-flight before boot: the served bootstrap bundle must carry the module face
const res = await fetch(`/plugins/@deepseek-ai/dsh-client-modules/client.js?rev=${rev}`)
const text = await res.text()
if (!res.ok || !text.includes('createClientModuleSystem')) {
  throw new Error('bootstrap bundle missing the module face — rebuild and hard-reload')
}

Try / catch

try {
  system = window.__ModuleLoader__.create(options)
} catch (error) {
  reportBootFailure(error) // advise full rebuild + cache clear; do not retry against the same bytes
  throw error
}

Prevention

When it happens

Trigger: The bytes served at /plugins/@deepseek-ai/dsh-client-modules/client.js?rev=... are not the current bootstrap bundle: a stale static copy or partially rebuilt tree, a proxy or service worker rewriting the path, or the package's exports["./client"] manifest edited to point at a different file. The factory returns exports lacking createClientModuleSystem or apply.

Common situations: Partial `pnpm run build` leaving one package's client bundle from an older protocol generation; hand-copying an old dist into a static directory next to the server; browser cache pinning an old bundle; mixed versions after switching branches without rebuilding.

Related errors


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