{"id":"cfb8664cf115b6d4","repo":"vitejs/vite","slug":"client-id-conflict-detected-please-restart-the-de","errorCode":null,"errorMessage":"client ID conflict detected. Please restart the dev server.","messagePattern":"client ID conflict detected\\. Please restart the dev server\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vite/src/node/server/bundledDev.ts","lineNumber":510,"sourceCode":"    if (truncated) debugHmr?.(`hmr update ${hmrOutput.changedIds.join(', ')}`)\n    this.environment.logger.info(\n      colors.green(`hmr update `) + colors.dim(formatted),\n      {\n        clear: true,\n        timestamp: true,\n      },\n    )\n  }\n}\n\nclass Clients {\n  private clientToId = new Map<NormalizedHotChannelClient, string>()\n  private idToClient = new Map<string, NormalizedHotChannelClient>()\n\n  setupIfNeeded(client: NormalizedHotChannelClient, clientId: string) {\n    const id = this.clientToId.get(client)\n    if (id && id !== clientId) {\n      throw new Error(\n        'client ID conflict detected. Please restart the dev server.',\n      )\n    }\n    this.clientToId.set(client, clientId)\n    this.idToClient.set(clientId, client)\n  }\n\n  get(id: string): NormalizedHotChannelClient | undefined {\n    return this.idToClient.get(id)\n  }\n\n  getId(client: NormalizedHotChannelClient): string | undefined {\n    return this.clientToId.get(client)\n  }\n\n  getAll(): NormalizedHotChannelClient[] {\n    return Array.from(this.idToClient.values())\n  }","sourceCodeStart":492,"sourceCodeEnd":528,"githubUrl":"https://github.com/vitejs/vite/blob/89620f09afcfef6b35e7bb8660132ab5b4d0cd3b/packages/vite/src/node/server/bundledDev.ts#L492-L528","documentation":"Clients.setupIfNeeded at packages/vite/src/node/server/bundledDev.ts:510 tracks hot-channel clients by an id reported in the vite:client-connected payload. If the same channel client object reconnects with a different clientId than the one it first registered, the dev server's bundled-dev state is inconsistent and it asks the user to restart.","triggerScenarios":"A hot channel reusing a client object across reconnects but generating a new clientId each time (e.g. HMR websocket re-handshaking with a fresh id); multiple browser tabs sharing a channel; a custom transport that does not preserve clientId identity for a given connection.","commonSituations":"Long-running dev sessions where the HMR socket reconnects after sleep/ network blip and the client id rotates; misbehaving custom transport / SSR hot channel; aggressive tab refresh loops.","solutions":["Restart the dev server as the message instructs to reset the client-id map.","If you author a custom hot channel, ensure a given client object always reports the same clientId.","Update Vite / the HMR client to a version that stabilizes clientId across reconnects.","Reduce reconnect churn (fix the proxy/network instability causing repeated HMR disconnects)."],"exampleFix":"// before: custom transport rotates id on reconnect\nclient = { send, on: cb => cb({ clientId: crypto.randomUUID() }) }\n\n// after: keep a stable id per client object\nconst id = crypto.randomUUID()\nclient = { send, on: cb => cb({ clientId: id }) }","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Restart the dev server when the message appears to reset the client-id map.","Author custom hot channels to keep a stable clientId per client object across reconnects.","Stabilize the network/proxy between the browser and the dev server to reduce HMR reconnects."],"tags":["hmr","dev-server","bundled-dev","hot-channel","client"],"analyzedSha":"89620f09afcfef6b35e7bb8660132ab5b4d0cd3b","analyzedAt":"2026-08-03T19:28:02.920Z","schemaVersion":2}