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
- Open the named file and inspect the //go:build line; balance parentheses and use only the supported operators (&&, ||, !).
- Run `go vet ./...` to get the precise parse error from the live toolchain.
- 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
- Run `go vet ./...` in pre-commit and CI.
- Use editor tooling (gopls) that reports build-constraint errors live.
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.