Skip to content

bug(codex/windows): run-bash-hook.ps1 waits for background children, so SessionStart times out when it starts engram serve #1471

Description

@lucasmiachon-blip

📝 Bug Description

On native Windows, plugin/codex/scripts/run-bash-hook.ps1 (v2.2.1) waits for its stdout and stderr copy tasks after bash exits: $process.WaitForExit(), then [System.Threading.Tasks.Task]::WaitAll(@($stdoutTask, $stderrTask)). Those tasks complete only at EOF.

A native Windows process that the hook script starts in the background inherits the redirected pipe handles, even when the script redirects the child's own stdout and stderr. session-start.sh starts the server exactly that way when it is not running (line 45):

ENGRAM_CLOUD_AUTOSYNC=1 engram serve > /dev/null 2>> "$ENGRAM_SERVE_ERR_LOG" &

The wrapper therefore waits until Codex's hook timeout (10 s here), and Codex drops the SessionStart output. The first session after a cold start gets no memory context.

🔄 Steps to Reproduce

Isolated repro; no Engram server needed.

  1. Copy plugin/codex/scripts/run-bash-hook.ps1 from v2.2.1 into an empty directory.
  2. Next to it, create session-start.sh. The wrapper runs only approved script names that sit next to it.
#!/usr/bin/env bash
ping -n 6 127.0.0.1 > /dev/null 2>> "$(dirname "$0")/child.err.log" &
printf '%s\n' '{"context":"repro"}'
exit 0
  1. Run powershell.exe -NoProfile -ExecutionPolicy Bypass -File <dir>\run-bash-hook.ps1 -HookScript <dir>\session-start.sh with stdin closed, and time it.
  2. For the control, run the same script without the ping line.

✅ Expected Behavior

The wrapper returns when bash exits, in about the time the control takes.

❌ Actual Behavior

  • With the background child, the wrapper took 5,362 ms, which is the lifetime of ping -n 6.
  • The control took 281 ms.
  • With engram serve as the child, the wait lasts until the hook timeout, so Codex discards the context block.

Operating System

Windows

Engram Version

2.2.0. The repro above used the v2.2.1 wrapper, unchanged.

Agent / Client

Other: Codex CLI 0.157.0, official Engram Codex plugin

📋 Relevant Logs

A real Codex 0.157.0 session on this host showed the same pattern:

  • serve.err.log recorded "listening" in the same second the session started.
  • The Codex log was silent for 10.55 s before the first model request.
  • The rollout contained no Engram block.

A later session, with the server already running, received the block after 1.5 s.

Versions: Windows 11 Pro 10.0.26200 x64, Windows PowerShell 5.1.26100.9444, Git for Windows bash 5.3.15.

💡 Additional Context

Either of these would fix it:

  • Start the server detached from the hook's handles, through a path that does not inherit the redirected handles.
  • Bound the drain after WaitForExit(): wait for the copy tasks with a short timeout, then exit with the process exit code.

Possibly related: #1454, which has a different trigger but the same symptom: the lifecycle HTTP server is unavailable while MCP still works.

Activity

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions