Skip to content

Stdin secret flags (--bearer-token -, --api-key -, …) fail under Node when input arrives late #2747

Closed

Description

@maxrabin

Description

Under Node, a secret flag read from stdin with - fails if the pipe is still empty when the CLI reads it:

Error: could not read '--bearer-token' from stdin

It works only if the data is already in the pipe. So the usual case, piping from a token command (az account get-access-token … | agentcore …), fails.

Steps to Reproduce

  1. Build the CLI (bun run build) and run it with Node (node dist/index.js).
  2. Pipe a valid JWT in with no delay (works):
    printf '%s\n' "$TOKEN" | node dist/index.js invoke --harness "$ARN" \
      --bearer-token - --prompt hi
  3. Pipe the same token in 2 seconds late (fails):
    (sleep 2; printf '%s\n' "$TOKEN") | node dist/index.js invoke --harness "$ARN" \
      --bearer-token - --prompt hi

The same failure in plain Node, without the CLI:

(sleep 2; echo hi) | node -e '
require("fs").createReadStream("", {fd: 0, autoClose: false})
  .on("data", d => console.log("got", String(d).trim()))
  .on("error", e => console.log("ERR", e.code, e.message))'
# got hi

(sleep 2; echo hi) | node -e '
process.stdin;
require("fs").createReadStream("", {fd: 0, autoClose: false})
  .on("data", d => console.log("got", String(d).trim()))
  .on("error", e => console.log("ERR", e.code, e.message))'
# ERR EAGAIN EAGAIN: resource temporarily unavailable, read

Expected Behavior

The CLI waits for stdin to close, then uses the value, however long the producer takes.

Actual Behavior

Step 2 works.
Step 3 fails right away with could not read '--bearer-token' from stdin, and the producer gets a broken pipe. --debug doesn't show the underlying EAGAIN.

CLI Version

1.0.1

Operating System

macOS

Additional Context

Cause: when stdin is process.stdin, SourceResolver.readStdin (src/io/source.ts) reads fd 0 directly with createReadStream("", { fd: 0, autoClose: false }). That works around Ink draining process.stdin under Bun. Under Node, touching process.stdin for a pipe makes fd 0 non-blocking. The raw read on the empty pipe then returns EAGAIN, and fs.ReadStream doesn't retry.

Suggested fix (untested): apply the fd-0 workaround only under Bun.

const source =
  this.config.stdin === process.stdin && process.versions.bun !== undefined
    ? createReadStream("", { fd: 0, autoClose: false })
    : this.config.stdin;

Testing note: bun test runs under Bun, and the unit tests inject stdin, so they can't hit this. A regression test has to run the built bundle under Node with late stdin. Including cause.code in the error message would also make this easier to diagnose.

Environment: Node v22.17.0, built with Bun 1.4.4, on v1.x (796277b) plus #2742 (37ce966). #2742 doesn't touch source.ts.

Activity

  1. changed the title [-]text Stdin secret flags (--bearer-token -, --api-key -, …) fail under Node when input arrives late[/-] [+]Stdin secret flags (--bearer-token -, --api-key -, …) fail under Node when input arrives late[/+] on Nov 3, 2026
  2. self-assigned this
    on Nov 3, 2026
  3. aetherxeg-source commented on Nov 3, 2026

    @aetherxeg-source

    @notgitika We reproduced the delayed-pipe failure mode on Node 22 with a small child-process test using synthetic input. After process.stdin has been initialized, a second fs.createReadStream on fd 0 fails with EAGAIN when the producer writes 350 ms later. Reading through the existing process.stdin stream succeeds with the same delayed input; the immediate-input control passes too.

    We have a focused regression test for this boundary. So far this is a Node runtime test, not a run of the built AgentCore CLI or a Bun compatibility check.

    Are you already covering delayed stdin in your fix? If not, we can contribute a targeted test without overlapping your implementation.

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions