unknwon/the-way-to-go_ZH_CN · error

Unknown user: no value for $USER

Error message

Unknown user: no value for $USER

What it means

Init-style guard from section 13.2: the package reads os.Getenv("USER") once at startup and check() panics with 'Unknown user: no value for $USER' when it is empty, refusing to run for an unidentified user. The text recommends performing such checks in an imported package's init() so the program fails immediately at load time.

Source

Thrown at eBook/13.2.md:44

       runtime.panic(0x442938, 0x4f08e8)
main.main+0xa5 E:/Go/GoBoek/code examples/chapter 13/panic.go:8
       main.main()
runtime.mainstart+0xf 386/asm.s:84
       runtime.mainstart()
runtime.goexit /go/src/pkg/runtime/proc.c:148
       runtime.goexit()
---- Error run E:/Go/GoBoek/code examples/chapter 13/panic.exe with code Crashed
---- Program exited with code -1073741783
```

一个检查程序是否被已知用户启动的具体例子:

```go
var user = os.Getenv("USER")

func check() {
	if user == "" {
		panic("Unknown user: no value for $USER")
	}
}
```

可以在导入包的 `init()` 函数中检查这些。

当发生错误必须中止程序时,`panic()` 可以用于错误处理模式:

```go
if err != nil {
	panic("ERROR occurred:" + err.Error())
}
```

<u>Go panicking</u>:

在多层嵌套的函数调用中调用 `panic()`,可以马上中止当前函数的执行,所有的 `defer` 语句都会保证执行并把控制权交还给接收到 panic 的函数调用者。这样向上冒泡直到最顶层,并执行(每层的) `defer`,在栈顶处程序崩溃,并在命令行中用传给 `panic()` 的值报告错误情况:这个终止过程就是 *panicking*。

View on GitHub (pinned to 7a54d34d36)

Solutions

  1. Set the variable before running: export USER=$(whoami) on Unix, or set USER=%USERNAME% on Windows
  2. Replace the panic with a runtime fallback: use os/user.Current().Username when USER is empty
  3. For services, configure the environment properly (systemd Environment=, docker -e USER=...)
  4. Fail with log.Fatal instead of panic so the process exits cleanly with the message

Example fix

// before
var user = os.Getenv("USER")
func check() {
    if user == "" {
        panic("Unknown user: no value for $USER")
    }
}

// after
func check() error {
    if os.Getenv("USER") == "" {
        if u, err := user.Current(); err == nil && u.Username != "" {
            os.Setenv("USER", u.Username)
            return nil
        }
        return errors.New("unknown user: no value for $USER")
    }
    return nil
}
Defensive patterns

Strategy: validation

Validate before calling

// run before the program (shell):
[ -z "$USER" ] && export USER="$(whoami)"

// or in Go, before calling anything that needs it:
if os.Getenv("USER") == "" {
    if u, err := user.Current(); err == nil {
        os.Setenv("USER", u.Username)
    }
}

Try / catch

defer func() {
    if r := recover(); r != nil {
        if strings.Contains(fmt.Sprint(r), "$USER") {
            log.Fatal("set USER and retry (Windows: set USER=%USERNAME%)")
        }
        panic(r)
    }
}()

Prevention

When it happens

Trigger: os.Getenv("USER") returns "": the variable is unset or empty in minimal shells, cron/systemd/Docker environments that scrub the environment, or on Windows where the conventional variable is USERNAME, not USER.

Common situations: Running the program on Windows; executing via crontab or a systemd unit without Environment= configured; slim Docker images with non-login shells; CI runners with restricted env.

Related errors


AI-assisted analysis of unknwon/the-way-to-go_ZH_CN@7a54d34d36 (2026-08-15). Data as JSON: /api/errors/6e5f9b24bdebcf62. Report an issue: GitHub.