golang/go · error
invalid command-line argument
Error message
invalid command-line argument %s in command: %s
What it means
Thrown by Shell.runOut when any argument in the command line passed to an external tool (gcc, ld, pkg-config, etc.) starts with `@`. GNU binutils interpret `@file` as "read more args from this file", which can be exploited via crafted filenames and is hard to escape safely, so the go command rejects such arguments outright.
Solutions
- Remove or rewrite any `@`-prefixed token in CGO_CFLAGS/CGO_LDFLAGS/#cgo directives.
- If a real path starts with `@`, rename it so it does not.
- Audit the offending source printed in the error (the full command is shown) to locate the `@` token.
- Avoid response-file (`@file`) conventions in cgo flags; pass flags inline.
Example fix
// before // #cgo CFLAGS: -I@root/include // after // #cgo CFLAGS: -I./include
Defensive patterns
Strategy: validation
Validate before calling
// Reject @-prefixed tokens in cgo flags before building
for _, env := range []string{"CGO_CFLAGS", "CGO_LDFLAGS", "CGO_CPPFLAGS", "CGO_CXXFLAGS"} {
for _, f := range strings.Fields(os.Getenv(env)) {
if strings.HasPrefix(f, "@") {
log.Fatalf("remove @-prefixed token %q from %s", f, env)
}
}
} Prevention
- Never embed response-file (@file) syntax in cgo flags.
- Rename any source/include path that starts with @.
- Audit generated flag lists for stray @ tokens.
When it happens
Trigger: A cgo build assembles a command line where some flag value or source path begins with `@` — e.g. CGO_CFLAGS contains `-I@incdir`, a source filename is `@evil`, or a generated response file leaks into an argument slot. runOut scans cmdline and returns before exec.
Common situations: A build system that emits `@file` response-file syntax into CGO flags; a filename or temp path that legitimately starts with `@`; a vendored C package whose #cgo line references an `@`-prefixed include; malicious/sanitized-fuzz input producing `@`-prefixed paths.
Related errors
- invalid flag in : (see https://go.dev/s/invalidflag)
- invalid flag in : (see https://go.dev/s/invalidflag)
- flag triggers external linking
- invalid flag in : without argument (see…
- invalid pkg-config package name
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/b45f4a78df5cf8cb.
Report an issue: GitHub.
Appendix: source
Thrown at src/cmd/go/internal/work/shell.go:598
}
return sh.reportCmd(desc, dir, out, err)
}
// runOut runs the command given by cmdline in the directory dir.
// It returns the command output and any errors that occurred.
// It accumulates execution time in a.
func (sh *Shell) runOut(dir string, env []string, cmdargs ...any) ([]byte, error) {
a := sh.action
cmdline := str.StringList(cmdargs...)
for _, arg := range cmdline {
// GNU binutils commands, including gcc and gccgo, interpret an argument
// @foo anywhere in the command line (even following --) as meaning
// "read and insert arguments from the file named foo."
// Don't say anything that might be misinterpreted that way.
if strings.HasPrefix(arg, "@") {
return nil, fmt.Errorf("invalid command-line argument %s in command: %s", arg, joinUnambiguously(cmdline))
}
}
if cfg.BuildN || cfg.BuildX {
var envcmdline string
for _, e := range env {
if j := strings.IndexByte(e, '='); j != -1 {
if strings.ContainsRune(e[j+1:], '\'') {
envcmdline += fmt.Sprintf("%s=%q", e[:j], e[j+1:])
} else {
envcmdline += fmt.Sprintf("%s='%s'", e[:j], e[j+1:])
}
envcmdline += " "
}
}
envcmdline += joinUnambiguously(cmdline)
sh.ShowCmd(dir, "%s", envcmdline)
if cfg.BuildN {View on GitHub (pinned to b6b368adc5)