docker/compose · error
--tty and --no-tty can't be used together
Error message
--tty and --no-tty can't be used together
What it means
`docker compose run` has both `--tty` and `--no-tty` flags; setting both in the same invocation is rejected because they directly contradict. The check uses Flags().Changed so even `--tty=false --no-tty=false` (both explicitly set) triggers the error.
Source
Thrown at cmd/compose/run.go:182
Args: cobra.MinimumNArgs(1),
PreRunE: AdaptCmd(func(ctx context.Context, cmd *cobra.Command, args []string) error {
options.Service = args[0]
if len(args) > 1 {
options.Command = args[1:]
}
if len(options.publish) > 0 && options.servicePorts {
return fmt.Errorf("--service-ports and --publish are incompatible")
}
if cmd.Flags().Changed("entrypoint") {
command, err := shellwords.Parse(options.entrypoint)
if err != nil {
return err
}
options.entrypointCmd = command
}
if cmd.Flags().Changed("tty") {
if cmd.Flags().Changed("no-tty") {
return fmt.Errorf("--tty and --no-tty can't be used together")
} else {
options.noTty = !ttyFlag
}
} else if !cmd.Flags().Changed("no-tty") && !cmd.Flags().Changed("interactive") && !dockerCli.In().IsTerminal() {
// while `docker run` requires explicit `-it` flags, Compose enables interactive mode and TTY by default
// but when compose is used from a script that has stdin piped from another command, we just can't
// Here, we detect we run "by default" (user didn't passed explicit flags) and disable TTY allocation if
// we don't have an actual terminal to attach to for interactive mode
options.noTty = true
}
if options.quiet {
display.Mode = display.ModeQuiet
backendOptions.Add(compose.WithEventProcessor(display.Quiet()))
}
createOpts.pullChanged = cmd.Flags().Changed("pull")
return nil
}),View on GitHub (pinned to ddc4b044b6)
Solutions
- Pass exactly one of `--tty` or `--no-tty`.
- Rely on compose's auto-detection: with no flags it enables TTY only when stdin is a terminal.
- In scripts, branch on a single boolean and emit only the corresponding flag.
Example fix
# before docker compose run --tty --no-tty web sh # after docker compose run --no-tty web sh
Defensive patterns
Strategy: validation
Validate before calling
# bash: single tty policy
TTY_ARGS=()
case "${TTY_MODE:-auto}" in tty) TTY_ARGS=(--tty);; no-tty) TTY_ARGS=(--no-tty);; auto) ;; *) echo "tty mode must be tty|no-tty|auto" >&2; exit 2;; esac
docker compose run "${TTY_ARGS[@]}" web Prevention
- Let compose auto-detect TTY when flags are unnecessary.
- Never template both --tty and --no-tty from separate booleans.
When it happens
Trigger: Running `docker compose run --tty --no-tty web`, or any invocation where both flags appear on the command line regardless of their values.
Common situations: Scripts templating both flags from independent booleans (`--tty=$TTY --no-tty=$NOTTY`); users adding --no-tty for piped input while --tty is already set by an alias or wrapper.
Related errors
- --service-ports and --publish are incompatible
- can't use --progress plain while ANSI support is forced
- --build and --no-build are incompatible
- --force-recreate and --no-recreate are incompatible
- label must be set as KEY=VALUE
AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15).
Data as JSON: /api/errors/a41af5ac3cfe3c5f.
Report an issue: GitHub.