{"record":{"id":"19c833d3a0a792d2","repo":"deepseek-ai/deepseek-harness","slug":"web-boot-string-failures-length-entr-failure","errorCode":null,"errorMessage":"web boot: ${String(failures.length)} entr${failures.length === 1 ? 'y' : 'ies'} did not activate\\n${failures.join('\\n')}","messagePattern":"web boot: (.+?) entr(.+?) did not activate\\\\n(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/client/web/src/boot.ts","lineNumber":156,"sourceCode":"  private assertEntriesActive(ctx: Context): void {\n    const failures: string[] = []\n    for (const entry of ctx.loader.entries()) {\n      const name = entry.options.name\n      if (entry.fiber === undefined) {\n        failures.push(`${name}: import failed (see console for the import error)`)\n        continue\n      }\n      const state = STATE_LABELS[entry.fiber.state]\n      if (state === 'active') continue\n      if (state === 'pending') {\n        const missing = Object.keys(entry.fiber.inject).filter(service => ctx.get(service) === undefined)\n        failures.push(`${name}: pending (waiting for service${missing.length === 1 ? '' : 's'}: ${missing.join(', ') || 'unknown'})`)\n      } else {\n        failures.push(`${name}: ${state}`)\n      }\n    }\n    if (failures.length > 0) {\n      throw new Error(`web boot: ${String(failures.length)} entr${failures.length === 1 ? 'y' : 'ies'} did not activate\\n${failures.join('\\n')}`)\n    }\n  }\n}\n","sourceCodeStart":138,"sourceCodeEnd":160,"githubUrl":"https://github.com/deepseek-ai/deepseek-harness/blob/b150a551b8d465e31e418e1b2eaf5e79bbb7d28e/packages/client/web/src/boot.ts#L138-L160","documentation":"After the Cordis loader reaches quiescence, AppWebEntry.assertEntriesActive audits every manifest entry. An entry with no fiber failed its import; an entry whose fiber is not active either failed during apply or is still pending because a service it injects is provided by no loaded plugin. Each offending entry contributes one line and boot aborts with the aggregate list.","triggerScenarios":"A manifest plugin row throws during import (missing ./client export, broken build, stale bundle) or during apply, or stays pending because no loaded entry provides a service in its inject list — the provider plugin was removed, renamed, or itself failed to import.","commonSituations":"Adding a client plugin while missing one of the three registration surfaces (tsconfig.client.json aggregate reference, cordis.patch.yml row, bundle package.json dependency); renaming or removing a plugin whose service another entry injects; probing a live server against stale lib/client.js bundles after editing sources.","solutions":["Read the per-entry lines: 'import failed' means the browser console holds the import error — open it, rebuild that package (pnpm --filter <pkg> bundle), and hard-refresh.","For 'pending (waiting for service X)', find which plugin should provide service X and why it is absent: missing from cordis.patch.yml, failed to load, or the service name changed.","Verify the new-package checklist surfaces for the failing row: aggregate tsconfig reference, patch.yml row, bundle package.json dependency.","After fixing, hard-refresh so cached bundles are bypassed before re-testing."],"exampleFix":"# before — ui-foo row in cordis.patch.yml but its package missing from\n# packages/bundle/web-app/package.json → the row cannot import\nplugins:\n  - '@deepseek-ai/dsh-client-ui-foo'\n\n# after — also declare the dependency so the healed node_modules resolves the row\n# packages/bundle/web-app/package.json\n\"dependencies\": { \"@deepseek-ai/dsh-client-ui-foo\": \"workspace:*\" }","handlingStrategy":"try-catch","validationCode":"// preflight: every manifest row's package must be resolvable before serving\nfor (const row of manifest.plugins) {\n  try { require.resolve(row.id + '/package.json') }\n  catch { throw new Error(`manifest row ${row.id} has no installed package — check the bundle dependency`) }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await entry.run()\n} catch (err) {\n  // err.message carries per-entry lines: 'import failed' vs 'pending (waiting for service X)'\n  // route the fix by line kind; activation failures are deterministic — never retry boot in a loop\n  reportBootFailure(err.message)\n}","preventionTips":["Keep the three registration surfaces (tsconfig aggregate, cordis.patch.yml, bundle package.json) in one change when adding a plugin.","Rebuild bundles (pnpm --filter <pkg> bundle) before probing a live server; the registry serves lib/client.js, not sources.","Run pnpm run test:gui after touching client plugins so import/apply failures surface in CI, not on the boot page."],"tags":["web-boot","cordis","plugin-activation","dependency-injection","manifest"],"backgroundTag":"plugin-activation-failed","analyzedSha":"b150a551b8d465e31e418e1b2eaf5e79bbb7d28e","analyzedAt":"2026-08-24T18:12:29.105Z","schemaVersion":2},"datasetVersion":"2026-08-24T22:17:12.610Z"}