golangci/golangci-lint · error

can't parse args: %w

Error message

can't parse args: %w

What it means

Before the logger is set up, golangci-lint force-parses the command-line arguments with pflag (using UnknownFlags) to extract logging options. If pflag cannot parse the arguments (and it isn't a help request), the error is wrapped as `can't parse args: %w`. This happens very early, before any command logic runs.

Source

Thrown at pkg/commands/root.go:147

	// Ignore unknown flags because we will parse the command flags later.
	fs.ParseErrorsAllowlist = pflag.ParseErrorsAllowlist{UnknownFlags: true}

	opts := &rootOptions{}

	// Don't do `fs.AddFlagSet(cmd.Flags())` because it shares flags representations:
	// `changed` variable inside string slice vars will be shared.
	// Use another config variable here,
	// to not affect main parsing by this parsing of only config option.
	setupRootPersistentFlags(fs, opts)

	fs.Usage = func() {} // otherwise, help text will be printed twice

	if err := fs.Parse(safeArgs(fs, os.Args)); err != nil {
		if errors.Is(err, pflag.ErrHelp) {
			return nil, err
		}

		return nil, fmt.Errorf("can't parse args: %w", err)
	}

	return opts, nil
}

// Shorthands are a problem because pflag, with UnknownFlags, will try to parse all the letters as options.
// A shorthand can aggregate several letters (ex `ps -aux`)
// The function replaces non-supported shorthands by a dumb flag.
func safeArgs(fs *pflag.FlagSet, args []string) []string {
	var shorthands []string
	fs.VisitAll(func(flag *pflag.Flag) {
		shorthands = append(shorthands, flag.Shorthand)
	})

	var cleanArgs []string
	for _, arg := range args {
		if len(arg) > 1 && arg[0] == '-' && arg[1] != '-' && !slices.Contains(shorthands, string(arg[1])) {
			cleanArgs = append(cleanArgs, "--potato")

View on GitHub (pinned to ed7a235d2d)

Solutions

  1. Fix or remove the malformed argument flagged in the wrapped pflag error.
  2. Use long flags (--flag=value) instead of clustered/unknown shorthands.
  3. Quote arguments containing special characters (especially paths and values with spaces or '=').
  4. Inspect the exact os.Args being passed if launched from a script or wrapper.

Example fix

// before
golangci-lint run -file=main.go
// after
golangci-lint run --file=main.go  # or the correct flag, e.g. --show-stats
Defensive patterns

Strategy: validation

Validate before calling

// sanity-check args before invoking the binary
for _, a := range args {
    if a == "" || strings.ContainsAny(a, "\u2018\u2019\u201c\u201d") {
        return fmt.Errorf("malformed argument: %q", a)
    }
}

Try / catch

if _, err := forceRootParsePersistentFlags(); err != nil {
    if errors.Is(err, pflag.ErrHelp) {
        return nil // help requested, not a failure
    }
    log.Fatalf("arg parse failed: %v", err) // inspect the wrapped pflag cause
}

Prevention

When it happens

Trigger: Malformed command-line arguments: a shorthand that pflag tries to interpret letter-by-letter under UnknownFlags (e.g. `-=x`, stray `-` values), an `=` in an unexpected place, or arguments that look like flags but aren't valid for any command.

Common situations: Pasting commands with smart quotes or stray characters; passing unknown shorthands like `-abc`; scripts building args dynamically and injecting an empty or garbage token; flag typos that break early parsing before cobra sees them.

Understand the failure class

Background: "unknown output mode", "invalid value for flag", "expects true/false": fixing invalid flag value errors in CLI tools — this error's family across 24 libraries.

Related errors


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