fix(auth): fail the login prompt when stdin ends without an answer

Merged
ER
13h ago
+154-3

The login prompts read stdin with readline.question. When stdin ends before an answer (CI, coding agents, scripts, </dev/null), the callback never fires, the pending promise empties the event loop, and Node exits 0 right after printing Enter choice [1/2]:.

That hits two common paths:

  • firecrawl login without a terminal prints the menu and exits 0 with nothing saved.
  • firecrawl init --all (or -y) without --browser and without a key stops at step 1 and exits 0, so the skills step never runs and the caller sees success.

promptInput in src/utils/auth.ts now rejects when readline closes before an answer, with:

No input to log in with. Run "firecrawl login --browser", pass --api-key, or set FIRECRAWL_API_KEY.

Piped answers still work. Without a terminal, one line reader serves every prompt, so a pipe can answer several prompts in a row (printf '2\nfc-...\n' | firecrawl login), and a last answer without a trailing newline counts. Between prompts the reader pauses and unrefs stdin, so a pipe left open does not keep the process alive. Ctrl+C at the prompt still exits (130) instead of being treated as missing input. The callers already handle a rejected login: firecrawl login prints the error and exits 1, and init records the failed auth step, continues with the remaining steps, and exits 1 with "Setup incomplete: authentication failed".

Before and after, with an empty HOME and no FIRECRAWL_API_KEY:

$ firecrawl login </dev/null; echo $?
# before: login menu, then 0
# after:  the error above, then 1

$ firecrawl init --all --skip-install </dev/null; echo $?
# before: login menu, then 0, no skills installed
# after:  auth fails with the error above, skills install, then "Setup incomplete: authentication failed" and 1

This complements #328, which stops ensureAuthenticated() from reaching the menu without a terminal; this change covers login and init, which call the login flow directly. No version bump, so it ships with the next release.

Testing

  • New tests in src/__tests__/utils/auth.test.ts: the login menu and manual login reject when stdin ends without input, and a piped API key is still read, with or without a trailing newline, and successive prompts read successive piped lines. Both rejection tests time out without the fix.
  • pnpm test, pnpm type-check, pnpm format:check, pnpm build.

Found by Wildfire, Firecrawl's integration testing, while reproducing the failing cli-setup-mcp and cli-templates checks without a terminal.