Skip to content

uc machine init requires a TTY in non-interactive shells (could not open TTY) #386

Closed

Description

@joeblew999

Uncloud version: uc version 0.19.0

Problem

uc machine init cannot run in a non-interactive shell (CI, automation, a piped/backgrounded process) because its progress UI needs a TTY. Even with -y/--yes set, it fails:

$ uc machine init root@<ip> --no-dns -y    # run without a controlling TTY
Error: wait for cluster to be ready: bubbletea: error opening TTY: bubbletea: could not open TTY: open /dev/tty: device not configured

The -y/--yes help text says it "should be explicitly set when running non-interactively, e.g., in CI/CD pipelines", which implies non-interactive use is supported — but -y only auto-confirms prompts; the bubbletea progress view still requires /dev/tty. uc ctx (e.g. uc ctx rm) has the same TTY requirement.

Steps to reproduce

  1. From a process with no controlling terminal (CI runner, nohup, a script whose output is piped), run:
    uc machine init root@<server-ip> --no-dns -y
  2. It errors with could not open TTY instead of completing.

Workaround

Allocating a pseudo-TTY works — the cluster is actually created fine; only the progress spinner needs the TTY:

script -q /dev/null uc machine init root@<server-ip> --no-dns -y

Request

A non-interactive / plain-output mode for uc machine init (and uc ctx): detect the absence of a TTY and fall back to plain line-by-line log output (or add a --no-tui/--plain flag). That would let Uncloud be driven from CI and IaC tooling without a PTY hack.

Context

Hit while automating Uncloud-on-Hetzner provisioning with mise + OpenTofu: https://github.com/joeblew999/vm-uncloud

Activity

  1. joeblew999 commented on Jun 3, 2026

    @joeblew999
    Author

    Verified still present on the latest nightly build (2026-06-02), not just v0.19.0: uc machine init and uc ctx expose only -y/--yes — no --no-tui/--plain/non-interactive flag — and still require /dev/tty for the progress UI. So this is current, not fixed.

  2. miekg commented on Jun 3, 2026

    @miekg
    Contributor

    related: #286

  3. miekg commented on Jun 3, 2026

    @miekg
    Contributor

    curious (and you seem to be in a position where you can easily test), what does
    uc machine init root@<ip> --no-dns -y | cat do?

  4. joeblew999 commented on Jun 6, 2026

    @joeblew999
    Author

    Hit this on uc 0.19.0 (macOS client → single Hetzner Cloud node) in a non-interactive shell:

    Error: wait for cluster to be ready: bubbletea: error opening TTY:
    bubbletea: could not open TTY: open /dev/tty: device not configured
    

    One detail that might help: the failure is only the readiness spinner. By the time it errors, the cluster is already functional —

    • the remote daemon is installed and running,
    • the local context is created (uc context ls shows it, machine registered),
    • uc machine ls reports the machine Up.

    So recovery is just to skip the rest of init and run the remaining (headless-safe) steps by hand (uc machine ls, then uc deploy …). A --no-tui / CI=1 / no-TTY path that polls for readiness without bubbletea would make uc machine init complete in CI/automation. (-y alone doesn't avoid it.)

  5. joeblew999 commented on Jun 6, 2026

    @joeblew999
    Author

    Thanks @miekg. Fair question — I've since torn this cluster down to keep the account at €0, so I can't re-run it live this second, but I can confirm the exact variant on my next provision and post the output.

    Reasoning in the meantime, from the error itself (open /dev/tty: device not configured): uc/bubbletea is opening /dev/tty — the process's controlling terminal — directly for the readiness spinner, rather than gating on isatty(stdout). So … --no-dns -y | cat only redirects stdout; /dev/tty is still unopenable in a shell with no controlling terminal (CI, nohup, a non-interactive agent shell), so I'd expect it to fail identically. Happy to be proven wrong by the actual run.

    What does sidestep it is handing the process a PTY rather than redirecting stdout — e.g. on macOS/BSD script -q /dev/null uc machine init root@<ip> --no-dns -y (Linux: script -qec '…' /dev/null). That's the workaround I reached for.

    I'll run | cat vs script side by side next time I bring a node up and report the outputs here. If a --plain / --no-tui path that polls for readiness without bubbletea is on the table, that'd be the clean fix for CI/automation.

  6. joeblew999 commented on Jun 6, 2026

    @joeblew999
    Author

    Tested it. uc 0.19.0, fresh Hetzner Cloud node, non-interactive shell with no controlling terminal (the CI/agent case).

    uc machine init root@<ip> --no-dns -y | cat → install + cluster init complete, then:

    Cluster initialised with machine 'machine-…' and saved as context 'hetzner' …
    Error: wait for cluster to be ready: bubbletea: error opening TTY: bubbletea: could not open TTY: open /dev/tty: device not configured
    # exit 1
    

    So | cat does not help — it only redirects stdout; the readiness spinner opens /dev/tty (the controlling terminal) directly, which doesn't exist here, so it fails the same way. Note the cluster is fully initialised before the spinner errors — only the wait UI dies.

    script -q /dev/null uc machine init root@<ip> --no-dns -y (give it a PTY instead of redirecting) →

    Cluster initialised with machine 'machine-…' …
    Cluster is ready.
    # exit 0
    

    So a PTY fixes it; redirecting stdout doesn't. The clean fix would be to fall back to a plain/non-TUI renderer (or a --plain/--no-tui flag) that polls for readiness when /dev/tty isn't available, so uc machine init completes in CI/automation without script.

  7. psviderski commented on Jun 17, 2026

    @psviderski
    Owner

    @joeblew999 What actual environment do you run it so you get this error? I can't reproduce in my environments without a tty which bubbletea handles correctly.
    I'd appreciate if you can give a human response instead of this AI BS.

  8. added a commit that references this issue on Jun 18, 2026
    2f717a1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions