Skip to content

Interactive prompts from spawned child processes are swallowed; commands hang indefinitely #72

Description

@ark-archastro

Summary

When a child process spawned by aster (observed with aster deps --all, but the spawn setup likely affects aster services prerequisite steps too) shows an interactive prompt, the prompt is never visible to the user and the command hangs indefinitely with no output. The user cannot tell the difference between "working" and "waiting forever for a keypress."

Environment

  • aster 0.13.0/0.14.0 (Homebrew; the hang was observed with the CLI in this range — daemon binary was /opt/homebrew/Cellar/aster/0.13.0/bin/aster, aster --version now reports 0.14.0), macOS (Darwin 25.5.0)
  • Monorepo: firstlanding, worktree checkout
  • Child tool that prompted: pnpm 11.7.0 (mise install)
  • Observed 2026-08-28 in worktree ark-intern-billing-fe

What happened

aster deps --all ran for minutes with no progress. Process inspection showed:

84684  aster deps --all          (49s+ elapsed)
└─ 84685  pnpm install           (state Ss, cwd infra/services/intern)

The pnpm child was not working — it was waiting for a keypress on an interactive confirmation (pnpm's "modules directory will be removed and reinstalled" purge prompt, triggered by a store-path mismatch; see the companion firstlanding issue about .pnpm-store):

  • 0.42s CPU over 64s elapsed; main thread parked in kevent (idle event loop, confirmed with sample)
  • zero TCP connections (lsof — not downloading)
  • fd 0 = /dev/ttys036 (aster passed the user's TTY through as the child's stdin)
  • fd 12 = /dev/ttys036 opened read/write — the signature of a prompt library opening /dev/tty directly to render a prompt
  • fd 1/2 = pipes into aster

So the child believed it was interactive (stdin is a TTY) and prompted, but the prompt was never visible — either because it went to the piped stdout, or because aster's own live progress rendering overdrew the lines the prompt wrote to the TTY. The child then blocked forever reading the TTY, and aster showed nothing.

The failure has a second, quieter variant: when aster spawns the same tool without a TTY (e.g. inside aster services supervised steps), pnpm takes its non-interactive path and aborts with ERR_PNPM_ABORTED_REMOVE_MODULES_DIR_NO_TTY — a visible failure, which is strictly better than the silent hang, but shows the two spawn paths are configured inconsistently.

Repro

Any deps/target command that prompts reproduces it. A minimal generic repro without pnpm:

  1. In any aster project, point a target's command at a script that prompts, e.g. bash -c 'read -p "continue? " x; echo got $x'.
  2. Run the target via aster from an interactive terminal.
  3. aster displays its progress UI and never shows the prompt; the target hangs indefinitely. lsof -p <child> shows fd 0 on the session TTY and the process idle.

The real-world trigger we hit: a pnpm workspace whose node_modules/.modules.yaml storeDir disagrees with the store pnpm resolves at spawn time (bind node_modules to a local store with pnpm install --config.store-dir=$PWD/.pnpm-store, remove the config, then run aster deps --all). pnpm prompts for a purge confirmation and aster hangs.

Suggested direction

  • Spawn children with stdin not attached to the user's TTY (pipe closed or /dev/null), so well-behaved tools take their non-interactive path and fail fast with a visible error instead of hanging. Setting CI=true in child env would also flip most JS tooling to non-interactive, but changes other behaviors (e.g. pnpm defaults to --frozen-lockfile), so stdin isolation is the safer default.
  • Optionally: detect a child that is blocked reading a TTY (or idle with no output for N seconds) and surface a "child may be waiting for input" warning with the pid.

Workaround

Kill the child, fix the condition that prompted, rerun. For pnpm specifically: pnpm install --config.confirm-modules-purge=false from the workspace root before invoking aster.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions