vitejs/vite · error · Error

client ID conflict detected. Please restart the dev server.

Error message

client ID conflict detected. Please restart the dev server.

What it means

Clients.setupIfNeeded maps a hot channel client to its clientId. If the same client object is already registered with a different id, Vite throws because the client identity and the id are out of sync — usually a symptom of a stale/HMR-desynced connection. The message asks the user to restart the dev server.

Solutions

  1. Restart the dev server as the message suggests.
  2. Hard-reload the browser tab to drop stale HMR client state.
  3. If using a custom transport, ensure each new clientId is paired with a new client object (or call delete on the old mapping).
  4. Update Vite — this is often a transient HMR desync fixed in newer patches.

Example fix

// before — custom transport reuses client object with new id
client.emit('vite:client-connected', { clientId: newId })
// after — drop the old mapping first
clients.delete(oldClient)
client.emit('vite:client-connected', { clientId: newId })
Defensive patterns

Strategy: validation

Validate before calling

// For custom transports, ensure clientId mapping is unique
function assertNoClientIdConflict(clients, client, clientId) {
  const existing = clients.getId(client)
  if (existing && existing !== clientId) throw new Error('client ID conflict; restart dev server')
}

Try / catch

try {
  clients.setupIfNeeded(client, clientId)
} catch (e) {
  if (/client ID conflict/.test(e.message)) { await server.restart() }
  throw e
}

Prevention

When it happens

Trigger: A hot channel client reconnects (vite:client-connected / vite:client:connect) and presents a clientId that differs from the one previously bound to the same underlying transport client. Happens when HMR state diverges from the server's client map.

Common situations: Long-lived dev sessions with aggressive HMR, custom transports/proxies that reuse connection objects, or bugs in the HMR client that regenerate ids without dropping the old mapping.

Related errors


AI-assisted analysis of vitejs/vite@b4d66fee14 (2026-08-11). Data as JSON: /api/errors/cfb8664cf115b6d4. Report an issue: GitHub.

Appendix: source

Thrown at packages/vite/src/node/server/bundledDev.ts:502

    if (truncated) debugHmr?.(`hmr update ${hmrOutput.changedIds.join(', ')}`)
    this.environment.logger.info(
      colors.green(`hmr update `) + colors.dim(formatted),
      {
        clear: true,
        timestamp: true,
      },
    )
  }
}

class Clients {
  private clientToId = new Map<NormalizedHotChannelClient, string>()
  private idToClient = new Map<string, NormalizedHotChannelClient>()

  setupIfNeeded(client: NormalizedHotChannelClient, clientId: string) {
    const id = this.clientToId.get(client)
    if (id && id !== clientId) {
      throw new Error(
        'client ID conflict detected. Please restart the dev server.',
      )
    }
    this.clientToId.set(client, clientId)
    this.idToClient.set(clientId, client)
  }

  get(id: string): NormalizedHotChannelClient | undefined {
    return this.idToClient.get(id)
  }

  getId(client: NormalizedHotChannelClient): string | undefined {
    return this.clientToId.get(client)
  }

  getAll(): NormalizedHotChannelClient[] {
    return Array.from(this.idToClient.values())
  }

View on GitHub (pinned to b4d66fee14)