charmbracelet/crush · error
unsupported env flag: %s
Error message
unsupported env flag: %s
What it means
parseEnvShebang rejects `env` shebangs that use any flag other than -S (split-string). The dispatcher implements env rewriting itself rather than forwarding to a real /usr/bin/env, and deliberately refuses unknown flags because forwarding them to a real env binary would be a portability footgun.
Source
Thrown at internal/shell/dispatch.go:337
// 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 == "" {
return nil, errors.New("env -S requires a program")
}
}
if rest == "" {
return nil, errors.New("env: missing program name")
}
var prog, remainder string
if idx := strings.IndexAny(rest, " \t"); idx >= 0 {
prog = rest[:idx]
remainder = strings.TrimLeft(rest[idx+1:], " \t")
} else {
prog = restView on GitHub (pinned to 7944b8e522)
Solutions
- Replace the env flag with plain env form: `#!/usr/bin/env <interpreter>`.
- If you need a clean environment, unset variables in the script body instead of using `env -i`.
- Use `#!/usr/bin/env -S <interpreter> <args>` if the goal was argument splitting; only -S is supported.
- If the interpreter needs a custom PATH, export PATH at the top of the script rather than via env -P.
Example fix
// before #!/usr/bin/env -i bash set -e // after #!/usr/bin/env bash set -e
Defensive patterns
Strategy: validation
Validate before calling
// reject env flags other than -S in shebangs before shipping
for _, line := range lines {
if strings.HasPrefix(line, "#!") && strings.Contains(line, "env -") && !strings.Contains(line, "env -S ") {
return fmt.Errorf("unsupported env flag in shebang: %s", line)
}
} Try / catch
var unsupported bool
if strings.HasPrefix(err.Error(), "unsupported env flag:") {
unsupported = true
} Prevention
- Only use `#!/usr/bin/env -S ...` or plain `#!/usr/bin/env ...` shebangs.
- Replace env -i/-P patterns with in-script PATH/export handling.
- Add a repo lint rule rejecting env flags other than -S.
- Test scripts through the dispatcher, not just the kernel.
When it happens
Trigger: A script's shebang is an env form whose first token after `env` starts with '-' but is not exactly "-S", e.g. `#!/usr/bin/env -i bash`, `#!/usr/bin/env -P /opt/bin python`, or `#!/usr/bin/env --split-string bash`.
Common situations: Portable scripts using `env -i` for a clean environment; BSD/macOS scripts using `env -P` to override PATH lookup; scripts using the long form `--split-string`; NixOS wrappers emitting extra env flags.
Related errors
- env: missing program name
- env -S requires a program
- empty shebang
- 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/6274d7dc76a2f6a5.
Report an issue: GitHub.