Fix script discovery and output handling on Windows (WSL + Git Bash)#43
Conversation
Two related bugs hit users on Windows-hosted bash environments where marimo runs natively on Windows but the agent scripts run under a non-MSYS bash: 1. discover-servers.sh and execute-code.sh only treat OSTYPE=msys*/cygwin* as Windows. Under WSL pointed at a Windows-native marimo install, OSTYPE=linux-gnu and the scripts read ~/.local/state/marimo/servers, missing the real registry at $USERPROFILE\.marimo\servers. Fix: probe a candidate list (XDG path, ~/.marimo/servers, and a wslpath/cygpath translation of $USERPROFILE if available), pick the first that holds registry files, and infer is_windows from the chosen path rather than from OSTYPE. 2. The SSE parser in execute-code.sh reads with `IFS= read -r line` and matches "event:" / "data:" literally. marimo's server emits CRLF terminators per the SSE spec; `read -r` strips only the LF, so the trailing \r makes none of the case branches match on Git Bash *or* WSL. Result: stdout/stderr/done events are silently dropped — the user sees no output even though the code ran. Fix: strip the trailing \r from each line before the case match. Tested on Windows 11 / Git Bash with a live marimo session: discovery finds the running server, and `execute-code.sh -c "print(1+1)"` returns its output correctly.
There was a problem hiding this comment.
Pull request overview
This PR fixes Windows-hosted bash environment issues when marimo runs natively on Windows but the helper scripts run under Git Bash/WSL, improving both server discovery and SSE output parsing.
Changes:
- Update registry discovery to probe multiple candidate server-registry directories (XDG,
~/.marimo/servers, and translated$USERPROFILE/.marimo/servers) and infer “Windows PID registry” behavior from the selected path. - Fix SSE parsing on Windows by trimming trailing
\rsoevent:/data:prefix matching works with CRLF-terminated streams.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| scripts/execute-code.sh | Adds multi-path registry discovery and CRLF-safe SSE parsing so stdout/stderr/done events are not dropped on Windows shells. |
| scripts/discover-servers.sh | Adds multi-path registry discovery and updated Windows/native liveness probing behavior to find the correct registry under WSL/Git Bash. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| servers_dir="" | ||
| for d in "${candidates[@]}"; do | ||
| if [[ -d "$d" ]] && compgen -G "$d/*.json" >/dev/null 2>&1; then | ||
| servers_dir="$d" | ||
| break |
| servers_dir="" | ||
| for d in "${candidates[@]}"; do | ||
| if [[ -d "$d" ]] && compgen -G "$d/*.json" >/dev/null 2>&1; then | ||
| servers_dir="$d" | ||
| break |
Address Copilot's review on the previous commit: picking the first candidate directory that contains *.json files can lock onto a stale registry (e.g. leftover XDG entries from a previous WSL-side marimo run) and never check the candidate that holds the live server. Walk every candidate, apply per-candidate liveness rules (`kill -0` for POSIX/XDG, HTTP `/health` probe for Windows-native `~/.marimo/servers`), and aggregate the live entries. A stale POSIX registry can no longer shadow a live Windows-native one, and a user with two live marimos in different registries (rare but possible) sees both. Also dedupe candidates by string before iterating: on Git Bash, $HOME and $(cygpath -u "$USERPROFILE") typically resolve to the same path (e.g. /c/Users/foo), and without dedupe the same registry file is walked twice and the same server is listed twice. The dedupe is a tiny O(n^2) loop — the candidate list never exceeds a handful — and stays bash 3-compatible. Verified: on Git Bash with one live marimo, discover-servers.sh returns a single entry (was returning duplicates pre-dedupe). The "multiple instances found" path in execute-code.sh now also walks all candidates so its output matches the count it reports.
|
Thanks @copilot-pull-request-reviewer — both comments are pointing at the same real bug and I've fixed it in b98d015. What changed: picking the first candidate directory that contains registry files locks the script onto whichever registry happens to have stale entries first. A user with leftover entries under the XDG path but a live registry at The new logic walks every candidate directory, applies per-candidate liveness rules ( While testing, I also noticed I have not been able to verify on a real WSL system — same caveat as before. The |
Fixes #42.
Two related bugs hit users on Windows-hosted bash environments where marimo runs natively on Windows but the agent scripts run under a non-MSYS bash. Both are scoped to
scripts/discover-servers.shandscripts/execute-code.sh.Bug 1 — discovery picks the wrong registry path under WSL
Both scripts only treat
OSTYPE=msys*/cygwin*as Windows. Under WSL pointed at a Windows-native marimo install,OSTYPE=linux-gnuand the scripts read~/.local/state/marimo/servers, missing the real registry at$USERPROFILE\.marimo\servers.Fix: probe a candidate list — XDG path,
~/.marimo/servers, and (if$USERPROFILEis set) awslpath/cygpathtranslation of it — and pick the first directory that has registry files. Theis_windowsflag (used to decide betweenkill -0and an HTTP/healthprobe for liveness) is now inferred from whether the chosen path matches*/.marimo/servers, since that's what determines whether the registered PIDs are Windows-native.Bug 2 — SSE parser silently drops every event on Windows
execute-code.shreads the event stream withIFS= read -r lineand matchesevent:/data:literally. marimo's HTTP server emits CRLF terminators per the SSE spec;read -rstrips only the LF, so the trailing\rkeeps every literal-prefix pattern from matching on Git Bash and WSL. Result: stdout / stderr / done events are all dropped — the user sees no output even though the code ran.Fix: one-line
line="${line%$'\r'}"right after theread. Cheap to do unconditionally; works the same on POSIX systems (no CR to strip).Testing
bash -non both scripts (clean).--no-tokenmarimo session:discover-servers.shfinds the running server, andexecute-code.sh -c "print(1+1)"returns its output correctly.$USERPROFILEis set andwslpath -u(orcygpath -u) is on PATH, append the translated<USERPROFILE>/.marimo/serversas a candidate.Notes
No behaviour change on Linux/macOS native: the XDG path is checked first and remains the only candidate that has files there. The Windows-native
~/.marimo/serverspath is checked second and is only selected when it actually contains a registry file. Falling through to "no registry found" early-returns[]fromdiscover-servers.shexactly as before.