{"record":{"id":"43735878ae18e007","repo":"redis/node-redis","slug":"proxy-no-node-with-no-connections","errorCode":null,"errorMessage":"[Proxy] No node with no connections","messagePattern":"\\[Proxy\\] No node with no connections","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/test-utils/lib/fault-injector/proxied-fault-injector-cluster.ts","lineNumber":118,"sourceCode":"\n    const migratingResult = await this.proxyController.sendToClient(\n      connections[sourceNode.id][0],\n      sMigratingNotification\n    );\n\n    if (!migratingResult.success) {\n      throw new Error(\n        `[Proxy] Failed to send SMIGRATING notification: ${migratingResult.error}`\n      );\n    }\n\n    // 2. Simulate maintenance delay\n    await setTimeout(2_000);\n\n    const isNewDestination = params.destination_type === \"new\";\n\n    if (isNewDestination && !nodeWithoutConnections) {\n      throw new Error(`[Proxy] No node with no connections`);\n    }\n\n    const destinationNode = isNewDestination\n      ? nodeWithoutConnections!\n      : nodes.at(-1)!; // Get the last node as the destination\n\n    if (!destinationNode) {\n      throw new Error(`[Proxy] No destination node`);\n    }\n\n    const sMigratedNotification = buildSMigratedNotification([\n      {\n        targetNode: destinationNode,\n        slotRanges: slots,\n      },\n    ]);\n\n    const migratedResult = await this.proxyController.sendToClient(","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/redis/node-redis/blob/90fd0652bc3f2a0a1b2f79fa9096b02a86b0ac58/packages/test-utils/lib/fault-injector/proxied-fault-injector-cluster.ts#L100-L136","documentation":"triggerMigrate requires a node with zero active connections when destination_type === 'new' (a hidden node to migrate slots onto). If every node has at least one connection, nodeWithoutConnections is undefined and this error throws. The source comment notes this also requires the cluster client NOT to use minimizeConnections, otherwise all nodes tend to have connections.","triggerScenarios":"Calling triggerMigrate with destination_type: 'new' when the cluster client has opened connections to every node (e.g., minimizeConnections is false so the client eagerly connects to all masters), leaving no candidate hidden node.","commonSituations":"Cluster client configured with full connectivity to all nodes; a prior migration left connections on the previously-hidden node; test setup connected the client before triggering the migration.","solutions":["Ensure at least one cluster node has no active client connections before requesting a 'new' destination (the test must leave a hidden node available)","Use destination_type: 'existing' instead, which targets the last visible node and does not need a connectionless node","Confirm the cluster client is not using minimizeConnections=false connectivity that touches every node"],"exampleFix":"// before — no hidden node available\nawait proxiedFi.triggerAction({\n  type: 'migrate',\n  parameters: { slot_migration: 'all', destination_type: 'new' }\n});\n// Error: [Proxy] No node with no connections\n\n// after — use an existing destination instead\nawait proxiedFi.triggerAction({\n  type: 'migrate',\n  parameters: { slot_migration: 'all', destination_type: 'existing' }\n});","handlingStrategy":"validation","validationCode":"async function findConnectionlessNode(proxyController: ProxyController): Promise<ProxyNode | undefined> {\n  const [nodes, connections] = await Promise.all([\n    proxyController.getNodes(),\n    proxyController.getConnections(),\n  ]);\n  const parsed = nodes.ids.map(parseNodeId);\n  return parsed.find(n => {\n    const c = connections[n.id];\n    return !c || c.length === 0;\n  });\n}","typeGuard":"function canMigrateToNew(nodeWithoutConnections: ProxyNode | undefined): nodeWithoutConnections is ProxyNode {\n  return nodeWithoutConnections !== undefined;\n}","tryCatchPattern":"try {\n  await proxiedFi.triggerAction({ type: 'migrate', parameters: { destination_type: 'new', slot_migration: 'all' } });\n} catch (e) {\n  if (e instanceof Error && /No node with no connections/.test(e.message)) {\n  }\n  throw e;\n}","preventionTips":["Ensure the cluster client does not open connections to every node before a 'new' migration","Validate that a connectionless node exists before requesting destination_type 'new'","Fall back to destination_type 'existing' when no hidden node is available"],"tags":["fault-injection","proxy","cluster","migration","test-utils","configuration"],"backgroundTag":null,"analyzedSha":"90fd0652bc3f2a0a1b2f79fa9096b02a86b0ac58","analyzedAt":"2026-08-11T15:37:21.243Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}