#4256·kind

Bug: pkg/internal/cli/env lacks Cygwin/MSYS2 support and violates NO_COLOR spec

Author: mohitjoshi-heyCreated Sep 2, 2026Updated Sep 2, 2026
Labelskind/bug

What happened:

While auditing the CLI terminal detection logic in pkg/internal/cli/env/env.go, I noticed two edge-case issues in how terminal state is calculated:

  1. Missing Git Bash / MSYS2 / Cygwin support on Windows

    IsTerminal currently only checks:

    go
    isatty.IsTerminal(v.Fd())

    Windows MSYS/Cygwin environments, including Git Bash, may use pipes rather than native Windows console APIs. Because of this, isatty.IsTerminal() can return false, causing KIND to unnecessarily fall back to dumb-terminal behavior.

    The underlying go-isatty dependency already supports detecting these environments through isatty.IsCygwinTerminal().

  2. Incorrect handling of an empty NO_COLOR value

    IsSmartTerminal currently disables ANSI output whenever NO_COLOR is present:

    go
    if _, set := lookupEnv("NO_COLOR"); set {
        return false
    }

    However, the official NO_COLOR standard linked in the source states that NO_COLOR should only disable color when it is present and not an empty string.

    As a result:

    bash
    NO_COLOR="" kind get clusters

    currently disables smart-terminal features, even though an empty NO_COLOR value should preserve normal color behavior.

    The existing table-driven test in env_test.go also currently enforces this incorrect behavior:

    Name: "tty, NO_COLOR=",
    FakeEnv: map[string]string{"NO_COLOR": ""},
    IsSmart: false

What you expected to happen:

  1. Users running KIND inside Git Bash, MSYS2, or Cygwin environments on Windows should receive normal smart-terminal functionality, including colors and spinners where supported.

  2. Setting NO_COLOR to an empty string should not disable ANSI output or smart-terminal features:

    bash
    NO_COLOR="" kind <command>

    This should behave the same as NO_COLOR being unset, in accordance with the NO_COLOR standard.

How to reproduce it (as minimally and precisely as possible):

Bug 1 — Git Bash / MSYS terminal detection:

  1. Open Git Bash on Windows.
  2. Run any KIND command.
  3. Observe that KIND may detect the environment as a non-terminal and fall back to dumb-terminal behavior.

Bug 2 — Empty NO_COLOR:

Run the following in a normal Linux/macOS terminal:

bash
NO_COLOR="" kind get clusters

Expected: smart-terminal features and ANSI colors remain enabled.

Actual: ANSI output is disabled because NO_COLOR is detected as present, despite having an empty value.

Alternatively, this can be seen directly in the existing env_test.go test case:

Name: "tty, NO_COLOR=",
FakeEnv: map[string]string{"NO_COLOR": ""},
IsSmart: false

Anything else we need to know?:

The fixes appear to be straightforward.

For IsTerminal, the existing go-isatty support for Cygwin/MSYS terminals could be used:

go
if v, ok := w.(*os.File); ok {
    return isatty.IsTerminal(v.Fd()) || isatty.IsCygwinTerminal(v.Fd())
}

For IsSmartTerminal, NO_COLOR should only disable smart-terminal functionality when its value is non-empty:

go
if val, set := lookupEnv("NO_COLOR"); set && val != "" {
    return false
}

I would also update the corresponding table-driven tests in env_test.go to validate both behaviors.

If the issue are valid then I would like to open a PR implementing these changes if the maintainers agree with the approach.

Environment:

  • kind version: v0.24.0 / latest main branch at commit e7f2238
  • Runtime info: N/A — this is a CLI terminal-detection issue
  • OS: Bug 1 affects Windows MSYS2/Cygwin environments such as Git Bash; Bug 2 affects all platforms
  • Kubernetes version: N/A
  • Any proxies or other special environment settings?: MSYS2/Cygwin (Git Bash) for Bug 1