golangci/golangci-lint · error

update plugin file: %w

Error message

update plugin file: %w

What it means

Builder.Build, after cloning, rewrites the plugins file to add imports of the user's custom plugin modules. Failure of b.updatePluginsFile() is wrapped as "update plugin file: %w" — the plugin manifest in the cloned tree couldn't be read or modified.

Source

Thrown at pkg/commands/internal/builder.go:55

		root: root,
		repo: filepath.Join(root, "golangci-lint"),
	}
}

// Build builds the custom binary.
func (b Builder) Build(ctx context.Context) error {
	b.log.Infof("Cloning golangci-lint repository")

	err := b.clone(ctx)
	if err != nil {
		return fmt.Errorf("clone golangci-lint: %w", err)
	}

	b.log.Infof("Adding plugin imports")

	err = b.updatePluginsFile()
	if err != nil {
		return fmt.Errorf("update plugin file: %w", err)
	}

	b.log.Infof("Adding replace directives")

	err = b.addToGoMod(ctx)
	if err != nil {
		return fmt.Errorf("add to go.mod: %w", err)
	}

	b.log.Infof("Running go mod tidy")

	err = b.goModTidy(ctx)
	if err != nil {
		return fmt.Errorf("go mod tidy: %w", err)
	}

	b.log.Infof("Building golangci-lint binary")

View on GitHub (pinned to ed7a235d2d)

Solutions

  1. Read the wrapped cause to see whether a plugin entry or the repo file layout is the problem.
  2. Validate every plugin entry in .custom-gcl.yml has a correct module path and version.
  3. Use a golangci-lint version compatible with your golangci-lint custom builder version.
  4. Check the temp directory is writable and has enough disk space, then re-run.

Example fix

// before (.custom-gcl.yml)
plugins:
  myplugin:      # missing module spec
// after
plugins:
  myplugin:
    module: example.com/myplugin
    version: v1.0.0
Defensive patterns

Strategy: validation

Validate before calling

// validate .custom-gcl.yml plugin entries before building
type plugin struct{ Module, Version string }
for name, p := range cfg.Plugins {
  if p.Module == "" || p.Version == "" {
    return fmt.Errorf("plugin %q needs both module and version", name)
  }
}
// temp dir must be writable
tmp, err := os.MkdirTemp("", "golangci-custom")
if err != nil { return err }
defer os.RemoveAll(tmp)

Try / catch

if err := customCmd.Run(); err != nil {
  if strings.Contains(err.Error(), "update plugin file") {
    log.Fatalf("check plugin entries and builder/version compatibility: %v", errors.Unwrap(err))
  }
  return err
}

Prevention

When it happens

Trigger: Running `golangci-lint custom` when updatePluginsFile fails: the cloned tree's plugins file is missing/unexpected (version mismatch with the expected layout), a plugin entry in .custom-gcl.yml is malformed, or the temp dir is not writable.

Common situations: Plugin entries in .custom-gcl.yml lacking a valid module path; building a golangci-lint version whose internal file layout the builder doesn't expect; disk/permission issues in the temp directory.

Related errors


AI-assisted analysis of golangci/golangci-lint@ed7a235d2d (2026-09-02). Data as JSON: /api/errors/1e10c9614a7ca375. Report an issue: GitHub.