golang/go · error
invalid command-line argument %s in command: %s
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.
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)
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 %s: %s %s (see https://go.dev/s/invalidflag)
- invalid flag in %s: %s (see https://go.dev/s/invalidflag)
- unexpected shell character %q in pkgconf output
- invalid pkg-config package name: %s
- flag %q triggers external linking
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/b45f4a78df5cf8cb.
Report an issue: GitHub.