charmbracelet/crush · error
env: missing program name
Error message
env: missing program name
What it means
parseEnvShebang found an '#!/usr/bin/env' style shebang with no interpreter program named after env. env needs at least a program name to execute, so the parser rejects the line.
Source
Thrown at internal/shell/dispatch.go:323
// isEnvShebang reports whether the shebang path targets `env`. We accept
// both common absolute paths and a bare `env` so that unusual setups
// (NixOS, BSDs) still work.
func isEnvShebang(p string) bool {
if p == "/usr/bin/env" || p == "/bin/env" {
return true
}
return filepath.Base(p) == "env"
}
// parseEnvShebang handles `/usr/bin/env` rewriting. Without `-S`, the
// remainder after the program name is a single argv[1] (kernel
// single-arg semantics via env, even though real env would fail to find a
// program named "bash -x"). With `-S`, the remainder is tokenized on
// whitespace. Any other `env` flag is rejected — forwarding unknown flags
// to a /usr/bin/env on disk is a subtle portability footgun we don't want.
func parseEnvShebang(rest string) (*shebang, error) {
if rest == "" {
return nil, errors.New("env: missing program name")
}
useSplit := false
if strings.HasPrefix(rest, "-") {
var flag, after string
if idx := strings.IndexAny(rest, " \t"); idx >= 0 {
flag = rest[:idx]
after = strings.TrimLeft(rest[idx+1:], " \t")
} else {
flag = rest
after = ""
}
if flag != "-S" {
return nil, fmt.Errorf("unsupported env flag: %s", flag)
}
useSplit = true
rest = after
if rest == "" {View on GitHub (pinned to 7944b8e522)
Solutions
- Add the interpreter name after env: e.g. '#!/usr/bin/env bash' or '#!/usr/bin/env -S python3 -u'.
- If using -S split-mode, make sure the program follows the flag on the same line.
- Validate the script's first line before dispatching it in tooling.
Example fix
// before #!/usr/bin/env // after #!/usr/bin/env bash
Defensive patterns
Strategy: validation
Validate before calling
line, _ := bufio.NewReader(f).ReadString('\n')
rest := strings.TrimSpace(strings.TrimPrefix(strings.TrimSpace(line), "#!"))
if strings.HasPrefix(rest, "#!/usr/bin/env") && strings.TrimSpace(strings.TrimPrefix(rest, "#!/usr/bin/env")) == "" {
return errors.New("env shebang missing interpreter")
} Try / catch
if err := dispatch(script); err != nil {
if strings.Contains(err.Error(), "missing program name") {
return fmt.Errorf("%s: add an interpreter after /usr/bin/env", script)
}
return err
} Prevention
- Never write '#!/usr/bin/env' without a program name.
- With -S, verify the interpreter follows the flag.
- Lint shebangs in CI before shipping scripts.
When it happens
Trigger: A shebang like '#!/usr/bin/env' (nothing after), or '#!/usr/bin/env -S' where -S consumed the rest and left an empty program string.
Common situations: A truncated or hand-edited shebang line missing the interpreter (e.g. someone deleted 'python3' from '#!/usr/bin/env python3').
Related errors
- env -S requires a program
- empty shebang
- unsupported env flag: %s
- interpreter %q not found in PATH
- interpreter %q not found and %q not in PATH
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/695e3f925194d986.
Report an issue: GitHub.