Reported from use: gitbay repo secret set krz/gitbay SONAR_TOKEN "felt like it hung both before and after I entered the token."
Both halves of that are real, and the second is the worse one.
Before typing. runSecretSet does io.ReadAll(io.LimitReader(c.Stdin, 64<<10)) (internal/control/build.go). With stdin on a terminal it blocks with nothing printed. There is no prompt, no "waiting", nothing — identical to a wedged connection.
After typing. Pressing Enter does not end the input; the read continues until EOF, which needs Ctrl-D. So having done the right thing, the user sees exactly what they saw before, and the success line (secret NAME set on ...) only arrives once EOF is sent. Nothing anywhere says Ctrl-D.
The token also echoes to the terminal and stays in scrollback, which is a poor end for a credential whose whole handling rule is that it never appears in argv, logs or output.
The client already knows this is coming: repo secret set is registered alwaysStdin: true (cmd/gitbay/main.go), and passOpts.stdinModeName() exists to report exactly this. It simply never checks whether stdin is a terminal.
Affects every alwaysStdin command — repo secret set, keys add, auth pgp add — and, less severely, the stdinOK commands invoked with --file -.
Remedy, client-side, where the terminal actually is:
- When stdin is a TTY and the command takes stdin as its payload, write one line to stderr before connecting: what it is reading, and that Ctrl-D ends it.
- For a secret specifically, read it without echo rather than letting it land in scrollback, and treat the first line as the value so Enter is enough.
- Keep the piped path byte-identical —
printf %s "$T" | gitbay ...must not grow a prompt or lose a trailing byte.
The server side needs no change; the terminal is a client fact and the daemon cannot see it.
closed by commit 47b439b55a by cmc: cli: a command reading stdin on a terminal says so
2026-09-04 19:43 UTC