golang/go · error

-C flag must be first flag on command line

Error message

-C flag must be first flag on command line

What it means

Returned by ChdirFlag, which is registered on subcommand flag sets by AddChdirFlag purely so usage/help is consistent. The global `-C dir` must appear before the subcommand; main.go strips it before subcommand parsing. ChdirFlag unconditionally returns this error, so any `-C` that reaches subcommand flag parsing is in the wrong position and is rejected.

Source

Thrown at src/cmd/go/internal/base/flag.go:84

}

// AddModFlag adds the -mod build flag to the flag set.
func AddModFlag(flags *flag.FlagSet) {
	flags.Var(explicitStringFlag{value: &cfg.BuildMod, explicit: &cfg.BuildModExplicit}, "mod", "module download `mode` to use: readonly, vendor, mod")
}

// AddModCommonFlags adds the module-related flags common to build commands
// and 'go mod' subcommands.
func AddModCommonFlags(flags *flag.FlagSet) {
	flags.BoolVar(&cfg.ModCacheRW, "modcacherw", false, "leave newly-created directories in the module cache read-write instead of making them read-only")
	flags.StringVar(&cfg.ModFile, "modfile", "", "read (and possibly write) an alternate go.mod `file` instead of the one in the module root directory")
	flags.StringVar(&fsys.OverlayFile, "overlay", "", "read a JSON config `file` that provides an overlay for build operations")
}

func ChdirFlag(s string) error {
	// main handles -C by removing it from the command line.
	// If we see one during flag parsing, that's an error.
	return fmt.Errorf("-C flag must be first flag on command line")
}

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Place `-C dir` immediately after `go` and before the subcommand: `go -C dir build ./...`.
  2. Alternatively `cd` into the target directory before running the go command.
  3. Do not pass `-C` to subcommands; it is a global flag only.

Example fix

// before
go build -C ../myproj ./...
// after
go -C ../myproj build ./...
Defensive patterns

Strategy: validation

Validate before calling

// Enforce that -C, if present, is the first global flag.
args := os.Args[1:]
for i, a := range args {
    if a == "-C" || strings.HasPrefix(a, "-C=") {
        if i != 0 && !isGlobalPosition(args, i) {
            return errors.New("-C flag must be first flag on command line; use: go -C <dir> <subcommand>")
        }
    }
}

Prevention

When it happens

Trigger: Running the go command with `-C` after the subcommand or anywhere other than the first global position, e.g. `go build -C dir ./...` or `go test ./... -C dir`.

Common situations: Assuming `-C` behaves like other build flags and works post-subcommand; copying `-C` into a script/CI command in the wrong position; muscle memory from tools that accept chdir flags anywhere.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/fe75110214e67140. Report an issue: GitHub.