Behavior: every command — including body-less GETs and --dry-run — blocks forever when stdin is a held-open pipe or socket. tail -f /dev/null | growthbook projects list hangs with zero output; CI runners and agent harnesses that keep the child's stdin open hit this constantly.
Root cause: BuildRequest's "Priority 2: stdin" branch calls io.ReadAll(stdin) whenever stdin is a non-char-device, without checking whether the operation takes a body at all.
Carried fix: .speakeasy/patches/internal/flagutil/metadata.go.patch (PR #48) gates the read on bodyFlagName != "". Body-taking ops keep the stdin-as-body feature (a held-open pipe still blocks those — defensible, documented behavior; see also #25).
Retire when: Speakeasy's generated flagutil/metadata.go skips the stdin read for no-body operations.
Behavior: every command — including body-less GETs and
--dry-run— blocks forever when stdin is a held-open pipe or socket.tail -f /dev/null | growthbook projects listhangs with zero output; CI runners and agent harnesses that keep the child's stdin open hit this constantly.Root cause:
BuildRequest's "Priority 2: stdin" branch callsio.ReadAll(stdin)whenever stdin is a non-char-device, without checking whether the operation takes a body at all.Carried fix:
.speakeasy/patches/internal/flagutil/metadata.go.patch(PR #48) gates the read onbodyFlagName != "". Body-taking ops keep the stdin-as-body feature (a held-open pipe still blocks those — defensible, documented behavior; see also #25).Retire when: Speakeasy's generated
flagutil/metadata.goskips the stdin read for no-body operations.