Fix 'make dev' failure in Windows environment#3236
Open
tanghang97 wants to merge 2 commits into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR aims to make make dev work reliably on Windows by applying a Windows-compatible asyncio event loop policy and improving cross-platform startup scripting (Python selection + port readiness checks).
Changes:
- Add Windows-specific asyncio event loop policy configuration (both in gateway startup and via
sitecustomize.py). - Improve
serve.shPython interpreter selection to work better in Windows/Git Bash environments. - Extend
wait-for-port.shto detect listening ports viapowershell.exeon Windows.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| scripts/wait-for-port.sh | Adds a PowerShell-based port listening probe for Windows. |
| scripts/serve.sh | Adds _pick_python() and uses it for Better Auth secret generation and uv-extras detection. |
| backend/sitecustomize.py | New module to set Windows asyncio event loop policy at Python startup. |
| backend/app/gateway/app.py | Adds Windows asyncio policy setup and modifies lifespan config/runtime initialization. |
Comment on lines
193
to
195
| # Initialize LangGraph runtime components (StreamBridge, RunManager, checkpointer, store) | ||
| async with langgraph_runtime(app, startup_config): | ||
| async with langgraph_runtime(app): | ||
| logger.info("LangGraph runtime initialised") |
Comment on lines
181
to
185
| # Load config and check necessary environment variables at startup | ||
| try: | ||
| startup_config = get_app_config() | ||
| apply_logging_level(startup_config.log_level) | ||
| app.state.config = get_app_config() | ||
| apply_logging_level(app.state.config.log_level) | ||
| logger.info("Configuration loaded successfully") |
Comment on lines
+24
to
+26
| if command -v powershell.exe >/dev/null 2>&1; then | ||
| if powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "\$ErrorActionPreference='SilentlyContinue'; if (Get-NetTCPConnection -LocalPort $PORT -State Listen) { exit 0 } else { exit 1 }" >/dev/null 2>&1; then | ||
| return 0 |
|
|
||
| _pick_python() { | ||
| local candidate | ||
| for candidate in python3 python py; do |
Comment on lines
+4
to
+21
|
|
||
| import asyncio | ||
| import sys | ||
|
|
||
|
|
||
| def _configure_windows_event_loop_policy() -> None: | ||
| if sys.platform != "win32": | ||
| return | ||
|
|
||
| selector_policy = getattr(asyncio, "WindowsSelectorEventLoopPolicy", None) | ||
| if selector_policy is None: | ||
| return | ||
|
|
||
| if not isinstance(asyncio.get_event_loop_policy(), selector_policy): | ||
| asyncio.set_event_loop_policy(selector_policy()) | ||
|
|
||
|
|
||
| _configure_windows_event_loop_policy() |
WillemJiang
reviewed
May 26, 2026
| async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: | ||
| """Application lifespan handler.""" | ||
|
|
||
| # Load config and check necessary environment variables at startup. |
Collaborator
There was a problem hiding this comment.
Please revert the change to the startup_config, which was just updated 5 days ago.
Collaborator
|
@tanghang97 thanks for your contribution. Please review the comments and fix the lint errors. |
2cd6101 to
2d21e5e
Compare
Comment on lines
+24
to
+28
| if command -v powershell.exe >/dev/null 2>&1; then | ||
| if powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "\$ErrorActionPreference='SilentlyContinue'; if (Get-NetTCPConnection -LocalPort $PORT -State Listen) { exit 0 } else { exit 1 }" >/dev/null 2>&1; then | ||
| return 0 | ||
| fi | ||
| fi |
Comment on lines
+40
to
+49
| _pick_python() { | ||
| local candidate | ||
| for candidate in python3 python py; do | ||
| if command -v "$candidate" >/dev/null 2>&1 && "$candidate" -c 'import sys' >/dev/null 2>&1; then | ||
| printf '%s\n' "$candidate" | ||
| return 0 | ||
| fi | ||
| done | ||
| return 1 | ||
| } |
Comment on lines
+35
to
+48
| def _configure_windows_event_loop_policy() -> None: | ||
| """Use an event loop policy compatible with async psycopg on Windows.""" | ||
| if sys.platform != "win32": | ||
| return | ||
|
|
||
| selector_policy = getattr(asyncio, "WindowsSelectorEventLoopPolicy", None) | ||
| if selector_policy is None: | ||
| return | ||
|
|
||
| if not isinstance(asyncio.get_event_loop_policy(), selector_policy): | ||
| asyncio.set_event_loop_policy(selector_policy()) | ||
|
|
||
|
|
||
| _configure_windows_event_loop_policy() |
Comment on lines
+1
to
+21
| """Process-wide Python startup customizations for local development.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import asyncio | ||
| import sys | ||
|
|
||
|
|
||
| def _configure_windows_event_loop_policy() -> None: | ||
| if sys.platform != "win32": | ||
| return | ||
|
|
||
| selector_policy = getattr(asyncio, "WindowsSelectorEventLoopPolicy", None) | ||
| if selector_policy is None: | ||
| return | ||
|
|
||
| if not isinstance(asyncio.get_event_loop_policy(), selector_policy): | ||
| asyncio.set_event_loop_policy(selector_policy()) | ||
|
|
||
|
|
||
| _configure_windows_event_loop_policy() |
WillemJiang
previously approved these changes
May 28, 2026
Collaborator
|
@tanghang97, could you take a look at the latest review message of Copilot? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR resolves the issue where
make devcommand fails to start properly in Windows environments. The fix addresses compatibility problems with asyncio event loop policy and improves cross-platform support for the development server startup process.Changes Made
1. Event Loop Policy Configuration (
backend/app/gateway/app.py)_configure_windows_event_loop_policy()function to handle Windows-specific asyncio requirementsWindowsSelectorEventLoopPolicyfor better async/await compatibility on Windows2. Site Customization (
backend/sitecustomize.py)3. Script Improvements (
scripts/serve.sh,scripts/wait-for-port.sh)powershell.exefor port listening verificationTechnical Details
sys.platform == "win32"to identify Windows environmentsWindowsSelectorEventLoopPolicywhich is more compatible with async libraries on Windowswait-for-port.shto use PowerShell'sGet-NetTCPConnectionon Windows systemsTesting
make devon Windows environmentsImpact
Related Issues
Resolves the Windows-specific startup failure that was blocking local development on Windows machines.
Fixes #3212