Skip to content

context-mode keeps pi-subagents child processes alive after final response #366

@ulusoyomer

Description

@ulusoyomer

Bug: context-mode causes pi-subagents child pi processes to timeout after completing task

Environment

  • context-mode: 1.0.99
  • pi-subagents: 0.19.3
  • pi: 0.70.2
  • Node: v24.12.0
  • OS: macOS / Darwin

Summary

When npm:context-mode is enabled in ~/.pi/agent/settings.json, every pi-subagents child process completes its assigned task and prints the correct final answer, but the child pi process does not exit. After 5000ms, pi-subagents force-terminates it and marks the run failed:

Subagent process did not exit within 5000ms after its final message. Forcing termination.

Removing only npm:context-mode fixes the issue immediately.

Reproduction

  1. Add context-mode to Pi global packages:
{
  "packages": [
    "npm:context-mode",
    "npm:pi-subagents"
  ]
}
  1. Restart Pi.
  2. Run a minimal subagent:
subagent({ agent: "delegate", task: "Say exactly \\"hello world\\" and nothing else." })
  1. The subagent prints the correct answer, but then fails with:
Subagent process did not exit within 5000ms after its final message. Forcing termination.

A/B test results

With npm:context-mode enabled

  • Single subagent: task output appears, but process times out after final message
  • Parallel subagents: tasks output correct answers, but runs fail with timeout
  • Chain runs: step output appears, but child process may fail with timeout

After removing only npm:context-mode

  • Single subagent succeeds
  • Parallel subagents: 2/2 succeeded
  • Chain: completed successfully

This was tested while keeping other variables stable. pi-intercom was also tested separately and does not reproduce the timeout when context-mode is disabled.

Likely root cause

pi-subagents spawns child pi processes using child_process.spawn("pi", args, { stdio: ["ignore", "pipe", "pipe"] }).

The child pi process completes the agent turn and writes its final response, but something loaded by context-mode appears to keep the Node event loop alive in that child process. Possible culprits:

  • context-mode hooks launched during subagent runs
  • background timers / intervals
  • open DB/file handles
  • watchers
  • pending IPC/subprocess handles

The package contains several hooks/background files, e.g. hooks/sessionstart.mjs, hooks/posttooluse.mjs, session DB/snapshot helpers, etc. It may need a subagent/non-interactive mode where long-lived handles are skipped or explicitly cleaned up.

Suggested fix

Detect subagent/non-interactive child Pi runs and avoid long-lived behavior there, or clean up all handles before process exit.

Possible approaches:

  1. Respect an env var such as PI_SUBAGENT=1 / PI_SUBAGENT_INHERIT_PROJECT_CONTEXT if present.
  2. Skip session capture/background hooks in child subagent processes.
  3. Add cleanup on beforeExit, exit, or Pi session shutdown events.
  4. Ensure any timers, DB handles, file watchers, or IPC handles are unref()ed or closed.

Related notes

We initially suspected pi-intercom/pi-subagents and opened issues there, but later closed them after isolating context-mode as the cause:

The actionable bug appears to be context-mode compatibility with pi-subagents child pi processes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions