golang/go · error

%s: invalid #cgo line: %s

Error message

%s: invalid #cgo line: %s

What it means

First #cgo validation failure in Context.saveCgo (modindex/build.go): a line beginning with '#cgo' was found in the import "C" comment, but it contained no colon (':') to separate the verb/conditions from its arguments. The %s is the source filename and the second %s is the offending raw line.

Source

Thrown at src/cmd/go/internal/modindex/build.go:444

		orig := line

		// Line is
		//	#cgo [GOOS/GOARCH...] LDFLAGS: stuff
		//
		line = strings.TrimSpace(line)
		if len(line) < 5 || line[:4] != "#cgo" || (line[4] != ' ' && line[4] != '\t') {
			continue
		}

		// #cgo (nocallback|noescape) <function name>
		if fields := strings.Fields(line); len(fields) == 3 && (fields[1] == "nocallback" || fields[1] == "noescape") {
			continue
		}

		// Split at colon.
		line, argstr, ok := strings.Cut(strings.TrimSpace(line[4:]), ":")
		if !ok {
			return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
		}

		// Parse GOOS/GOARCH stuff.
		f := strings.Fields(line)
		if len(f) < 1 {
			return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
		}

		cond, verb := f[:len(f)-1], f[len(f)-1]
		if len(cond) > 0 {
			ok := false
			for _, c := range cond {
				if ctxt.matchAuto(c, nil) {
					ok = true
					break
				}
			}
			if !ok {

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Add the required colon between the verb and the arguments: `#cgo CFLAGS: -O2`.
  2. Confirm no stray characters precede the colon; the form is `#cgo [GOOS/GOARCH...] VERB: args`.
  3. Rebuild with CGO_ENABLED=1 to re-exercise the cgo parser after the edit.

Example fix

// before
// #cgo CFLAGS -O2 -Wall
// after
// #cgo CFLAGS: -O2 -Wall
Defensive patterns

Strategy: validation

Validate before calling

// Lint cgo lines for a missing colon before invoking the build.
var cgoLineRe = regexp.MustCompile(`^#cgo\s+([^:]*):(.*)$`)

func lintCgoColon(line string) error {
    t := strings.TrimSpace(line)
    if !strings.HasPrefix(t, "#cgo") {
        return nil
    }
    if !cgoLineRe.MatchString(t) && !isCgoNoCallbackNoescape(t) {
        return fmt.Errorf("cgo line missing colon: %s", line)
    }
    return nil
}

Prevention

When it happens

Trigger: Writing a cgo directive without a colon, e.g. `// #cgo CFLAGS -O2` instead of `// #cgo CFLAGS: -O2`. saveCgo calls strings.Cut(line[4:], ':') and reaches the !ok branch.

Common situations: Translating a Makefile-style flag list into cgo comments and forgetting the colon syntax; mis-pasting a cgo line from documentation.

Related errors


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