{"record":{"id":"28d84571c4cc3ef6","repo":"CoplayDev/unity-mcp","slug":"port-port-is-already-in-use","errorCode":null,"errorMessage":"Port {port} is already in use.","messagePattern":"Port (.+?) is already in use\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"MCPForUnity/Editor/Helpers/PortManager.cs","lineNumber":99,"sourceCode":"        /// which distinguishes a domain-reload socket-release race from a foreign occupant (#1173).\n        /// </summary>\n        public static bool ShouldAbandonBusyPort(double busyForSeconds)\n            => busyForSeconds >= BusyPortFallbackWindowSeconds;\n\n        /// <summary>\n        /// Persist a user-selected port and return the value actually stored.\n        /// If <paramref name=\"port\"/> is unavailable, the next available port is chosen instead.\n        /// </summary>\n        public static int SetPreferredPort(int port)\n        {\n            if (port <= 0)\n            {\n                throw new ArgumentOutOfRangeException(nameof(port), \"Port must be positive.\");\n            }\n\n            if (!IsPortAvailable(port))\n            {\n                throw new InvalidOperationException($\"Port {port} is already in use.\");\n            }\n\n            SavePort(port);\n            return port;\n        }\n\n        /// <summary>\n        /// Find an available port starting from the default port\n        /// </summary>\n        /// <returns>Available port number</returns>\n        private static int FindAvailablePort()\n        {\n            // Always try default port first\n            if (IsPortAvailable(DefaultPort))\n            {\n                if (IsDebugEnabled()) McpLog.Info($\"Using default port {DefaultPort}\");\n                return DefaultPort;\n            }","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/CoplayDev/unity-mcp/blob/c21bf496bca87d54e75bad048563c3adb1782081/MCPForUnity/Editor/Helpers/PortManager.cs#L81-L117","documentation":"After the positive-port check passes, SetPreferredPort probes the port via IsPortAvailable (a TcpListener bind test on IPAddress.Loopback). If the port is already bound or otherwise unavailable, it throws InvalidOperationException. Note: the method's doc comment mentions choosing the next available port, but this specific method strictly refuses a busy port.","triggerScenarios":"Another process (a Unity instance, the Python MCP server, a dev server) already bound the port; a socket lingering in TIME_WAIT; the OS reserving the port.","commonSituations":"Multiple Unity/Server instances competing for the default port; a leftover process from a crashed session; the port held by an unrelated local service.","solutions":["Stop the conflicting process occupying the port, or choose a different port.","If you want automatic fallback rather than a hard refusal, use the FindAvailablePort path instead of SetPreferredPort.","Check for orphaned server processes after a crash before retrying."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"if (!PortManager.IsPortAvailable(port))\n    throw new InvalidOperationException($\"Port {port} is busy; stop the owning process or choose another.\");\nPortManager.SetPreferredPort(port);","typeGuard":null,"tryCatchPattern":"try { return PortManager.SetPreferredPort(port); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"already in use\"))\n{\n    // Fall back to automatic port discovery instead of refusing.\n    return FindAvailablePortWithFallback();\n}","preventionTips":["Probe IsPortAvailable before calling SetPreferredPort to give a clearer error.","Use the auto-find path when you do not require a specific port.","Stop orphaned server processes after crashes to free ports."],"tags":["port","network","concurrency","validation"],"backgroundTag":null,"analyzedSha":"c21bf496bca87d54e75bad048563c3adb1782081","analyzedAt":"2026-08-13T17:36:56.095Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}