e707c97ca6
Three issues caused the port to remain bound after partial failures: 1. VoiceCallWebhookServer.start() had no idempotency guard — calling it while the server was already listening would create a second server on the same port. 2. createVoiceCallRuntime() did not clean up the webhook server if a step after webhookServer.start() failed (e.g. manager.initialize). The server kept the port bound while the runtime promise rejected. 3. ensureRuntime() cached the rejected promise forever, so subsequent calls would re-throw the same error without ever retrying. Combined with (2), the port stayed orphaned until gateway restart. Fixes #32387 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>