golang/go · error

go %s%s%s: %v

Error message

go %s%s%s: %v

What it means

BuildInstallFunc wraps any error from the install action with the command name (cfg.CmdName, e.g. "build" or "install"), a separator, and the package import path. It is a user-facing prefix that contextualizes the underlying failure; the real cause is in the wrapped %v. For the -buildmode=shared action that installs a .so over multiple packages, a.Package is nil so the path is omitted.

Source

Thrown at src/cmd/go/internal/work/exec.go:2199

	// TODO(rsc): There is a missing updateBuildID here,
	// but we have to decide where to store the build ID in these files.
	a.built = a.Target
	return BuildToolchain.ldShared(b, a, a.Deps[0].Deps, a.Target, importcfg, a.Deps)
}

// BuildInstallFunc is the action for installing a single package or executable.
func BuildInstallFunc(b *Builder, ctx context.Context, a *Action) (err error) {
	defer func() {
		if err != nil {
			// a.Package == nil is possible for the go install -buildmode=shared
			// action that installs libmangledname.so, which corresponds to
			// a list of packages, not just one.
			sep, path := "", ""
			if a.Package != nil {
				sep, path = " ", a.Package.ImportPath
			}
			err = fmt.Errorf("go %s%s%s: %v", cfg.CmdName, sep, path, err)
		}
	}()
	sh := b.Shell(a)

	a1 := a.Deps[0]
	a.buildID = a1.buildID
	if a.json != nil {
		a.json.BuildID = a.buildID
	}

	// If we are using the eventual install target as an up-to-date
	// cached copy of the thing we built, then there's no need to
	// copy it into itself (and that would probably fail anyway).
	// In this case a1.built == a.Target because a1.built == p.Target,
	// so the built target is not in the a1.Objdir tree that b.cleanup(a1) removes.
	if a1.built == a.Target {
		a.built = a.Target
		if !a.buggyInstall {

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Read the wrapped error text after the colon - that is the real cause
  2. Address the underlying failure (missing module, compile error, permissions)
  3. Re-run with -x for full action tracing: `go install -x <pkg>`
Defensive patterns

Strategy: try-catch

Try / catch

// Unwrap the 'go <cmd> <pkg>: <cause>' wrapper to get the real error
out, err := cmd.CombinedOutput()
if err != nil {
    // The real cause follows the last ': ' in the first error line
    if i := bytes.LastIndex(out, []byte(": ")); i >= 0 {
        log.Printf("underlying cause: %s", out[i+2:])
    }
    return err
}

Prevention

When it happens

Trigger: Fires in the deferred error handler of BuildInstallFunc whenever err != nil after the install action body - covering link errors, copy errors, permission errors, or any downstream build failure.

Common situations: Any `go install` or `go build` failure - the wrapped %v is the actionable part (missing dependency, compile error, permission denied, link failure).

Related errors


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