Skip to content

Windows: web UI hangs — list_projects deadlocks the HTTP server (git via _popen handle inheritance) #798

Closed

Description

@Flipper1994

Windows: web UI hangs forever — list_projects deadlocks the HTTP server (git subprocess via _popen)

Summary

On Windows, with the graph UI enabled (--ui=true), the web UI never loads: the
page shell is served but the app stays blank. The cause is that the MCP tool
list_projects hangs forever and, because the UI HTTP server is
single-threaded, wedges the entire server — no further request is answered.

  • Affected: Windows, UI mode only (--ui=true / the web graph). Reproduced
    with the production binary built from main (cbm-with-ui).
  • Not affected: the plain MCP-stdio server (no UI) and the CLI — list_projects
    returns instantly there. That is why normal MCP usage never showed the problem.
  • Requires: git-for-Windows (the MSYS2/Cygwin build) on PATH, which is the
    standard Windows git.

Root cause (confirmed with a debugger)

list_projects resolves git context per project:
add_git_context_json → cbm_git_context_resolve → git_capture → cbm_popen
(src/git/git_context.c). On Windows cbm_popen is the CRT _popen, which spawns
the child with CreateProcess(bInheritHandles = TRUE) and therefore leaks every
inheritable handle
the server holds into the git child — including the
Winsock/AFD helper handles that only exist once the HTTP server has called
WSAStartup/socket().

git-for-Windows (MSYS2/Cygwin runtime) classifies every inherited handle on
startup by calling NtQueryObject on it. NtQueryObject deadlocks on an
inherited socket/AFD handle. So git never reaches rev-parse, never writes output,
and the server thread blocks forever in fgets on git's stdout pipe.

Three-thread deadlock captured with gdb on the hung process:

# UI request thread — waiting for git output that never comes
ntdll!ZwReadFile -> ReadFile -> msvcrt!fgets
  -> git_capture() (git_context.c)
  -> cbm_git_context_resolve -> add_git_context_json -> handle_list_projects
  -> cbm_mcp_server_handle -> cbm_http_server_run -> http_thread

# the git.exe child — stuck classifying an inherited handle
ntdll!ZwQueryObject   (NtQueryObject)

# server main thread — the blocking read on the MCP stdin pipe git inherited/queries
ntdll!ZwReadFile -> ... -> cbm_getline -> cbm_mcp_server_run

Why UI-only: the plain stdio server and the CLI have no listening/AFD socket
handles, so git inherits nothing that trips NtQueryObject.

Reproduction

  1. On Windows, build with the UI: make -f Makefile.cbm cbm-with-ui.
  2. Index any two git repos so list_projects returns >1 project.
  3. Run codebase-memory-mcp --ui=true --port=9749 and open the UI (or just
    POST /rpc {"method":"tools/call","params":{"name":"list_projects"}}).
  4. The request never returns; the whole UI server stops responding. tasklist
    shows a cmd /c git ... rev-parse child that never exits.

Fix

Spawn git so it inherits only the stdout pipe. See the PR: cbm_popen on
Windows is reimplemented with CreateProcess + STARTUPINFOEX and an explicit
PROC_THREAD_ATTRIBUTE_HANDLE_LIST (stdout write-end + a NUL handle for
stdin/stderr). Nothing else crosses into git → no foreign handle to deadlock on.
The POSIX path is unchanged (popen already sets O_CLOEXEC).

Activity

  1. added
    bugSomething isn't working
    windowsWindows-specific issues
    ux/behaviorDisplay bugs, docs, adoption UX
    stability/performanceServer crashes, OOM, hangs, high CPU/memory
    priority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.
    on Jul 4, 2026
  2. DeusData commented on Jul 4, 2026

    @DeusData
    Owner

    Thanks for the debugger-backed Windows UI hang report. Triage: high-priority Windows/UI stability under #394/#396.

    The root cause is actionable: UI mode creates inheritable socket/AFD handles, _popen leaks them into git-for-Windows, and list_projects wedges the single-threaded HTTP server. I see #799 is open for the handle-inheritance fix; review should verify the Windows process-spawn path closes that leak without changing POSIX behavior.

  3. added 2 commits that reference this issue on Jul 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.stability/performanceServer crashes, OOM, hangs, high CPU/memoryux/behaviorDisplay bugs, docs, adoption UXwindowsWindows-specific issues

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions