golang/go · error

%s: parsing //go:build line: %v

Error message

%s: parsing //go:build line: %v

What it means

Returned by IndexPackage.Import when constraint.Parse fails on a file's //go:build constraint line during indexed import. The %s is the bare source file name and %v is the parse error. This is the indexed-import analogue of the live go/build error for malformed build tags.

Source

Thrown at src/cmd/go/internal/modindex/read.go:510

		// Check errors for go files and call badGoFiles to put them in
		// InvalidGoFiles if they do have an error.
		if strings.HasSuffix(name, ".go") {
			if error := tf.error(); error != "" {
				badGoFile(name, errors.New(tf.error()))
				continue
			} else if parseError := tf.parseError(); parseError != "" {
				badGoFile(name, parseErrorFromString(tf.parseError()))
				// Fall through: we still want to list files with parse errors.
			}
		}

		var shouldBuild = true
		if !ctxt.goodOSArchFile(name, allTags) && !ctxt.UseAllFiles {
			shouldBuild = false
		} else if goBuildConstraint := tf.goBuildConstraint(); goBuildConstraint != "" {
			x, err := constraint.Parse(goBuildConstraint)
			if err != nil {
				return p, fmt.Errorf("%s: parsing //go:build line: %v", name, err)
			}
			shouldBuild = ctxt.eval(x, allTags)
		} else if plusBuildConstraints := tf.plusBuildConstraints(); len(plusBuildConstraints) > 0 {
			for _, text := range plusBuildConstraints {
				if x, err := constraint.Parse(text); err == nil {
					if !ctxt.eval(x, allTags) {
						shouldBuild = false
					}
				}
			}
		}

		ext := nameExt(name)
		if !shouldBuild || tf.ignoreFile() {
			if ext == ".go" {
				p.IgnoredGoFiles = append(p.IgnoredGoFiles, name)
			} else if fileListForExt(p, ext) != nil {
				p.IgnoredOtherFiles = append(p.IgnoredOtherFiles, name)

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Open the named file and inspect the //go:build line; balance parentheses and use only the supported operators (&&, ||, !).
  2. Run `go vet ./...` to get the precise parse error from the live toolchain.
  3. Validate the constraint against go/build/constraint in isolation if unsure of the grammar.

Example fix

// before
//go:build linux && (amd64 || arm64
// after
//go:build linux && (amd64 || arm64)
Defensive patterns

Strategy: validation

Validate before calling

// Pre-parse every //go:build line in the package's files.
import "go/build/constraint"

func lintPackageBuildConstraints(pkgDir string) error {
    entries, _ := os.ReadDir(pkgDir)
    for _, e := range entries {
        if !strings.HasSuffix(e.Name(), ".go") { continue }
        f, _ := os.Open(filepath.Join(pkgDir, e.Name()))
        hdr, _, _ := readHeaderComments(f) // your util
        f.Close()
        for _, line := range bytes.Split(hdr, []byte("\n")) {
            if bytes.HasPrefix(bytes.TrimSpace(line), []byte("//go:build")) {
                if _, err := constraint.Parse(string(line)); err != nil {
                    return fmt.Errorf("%s: %w", e.Name(), err)
                }
            }
        }
    }
    return nil
}

Prevention

When it happens

Trigger: A .go file in the package contains a //go:build line whose expression is syntactically invalid (unbalanced parens, unknown operators, trailing tokens). constraint.Parse returns an error that Import wraps.

Common situations: Editing build tags and introducing a syntax error; merging branches and leaving conflicting tags; using a future Go syntax not supported by the current toolchain.

Related errors


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