Skip to content

fix(core): cancel prompts when the input stream ends - #623

Open
MFA-G wants to merge 1 commit into
bombshell-dev:mainfrom
MFA-G:fix/cancel-on-input-end
Open

MFA-G wants to merge 1 commit into
bombshell-dev:mainfrom
MFA-G:fix/cancel-on-input-end

Conversation

@MFA-G

@MFA-G MFA-G commented Oct 19, 2026

Copy link
Copy Markdown

What does this PR do?

When the input stream ends while a prompt is waiting (or has already ended before it starts), prompt() never settles: it only resolves on submit/cancel, and nothing listens for the stream ending. With stdin from /dev/null, in CI or in agent shells, or with piped input that runs out before the last prompt, await confirm(...) hangs and Node exits with code 13 ("Detected unsettled top-level await"), leaving the cursor hidden.

This PR cancels the prompt in that case, so callers get the cancel symbol they already handle with isCancel(). That is the behavior the issue suggests.

  • Prompt#prompt() listens for end on the input and runs the same cancel path as Ctrl+C: state = 'cancel', finalize, render, close(). If the stream has already ended (readableEnded), the prompt cancels right away, because end will not be emitted again.
  • If the prompt has already been submitted or cancelled, an end event is ignored, and close() removes the listener so nothing leaks to the next prompt that shares stdin.

With the repro from the issue (built locally against this branch):

$ node repro.mjs < /dev/null
...
confirm settled with cancel
text settled with cancel
$ echo $?
0

On main the same command prints Warning: Detected unsettled top-level await and exits with 13.

Closes #615

Type of change

  • Bug fix
  • Feature
  • Refactor (no behavior change)
  • Documentation
  • Performance improvement
  • Tests
  • Chore (dependencies, CI, tooling)

Checklist

  • pnpm test passes (or targeted tests for my change)
  • pnpm format has been run
  • I have added/updated tests for my changes (if applicable)
  • I have added a changeset

Three new tests are in packages/core/test/prompts/prompt.test.ts: the input ends while a prompt is active, the input ended before the prompt started, and the input ends after a submit (the result must stay the submitted value). The first two time out on main. pnpm test passes (core 174, prompts 618), and pnpm types and biome check are clean.

AI-generated code disclosure

  • This PR includes AI-generated code

@changeset-bot

changeset-bot Bot commented Oct 19, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: cddd575

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@clack/core Patch
@clack/prompts Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@43081j 43081j left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems to make sense

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Prompts never settle when stdin ends

2 participants