urfave/cli · error

cannot set both flags `--%s` and `--%s`

Error message

cannot set both flags `--%s` and `--%s`

What it means

BoolWithInverseFlag is a boolean flag that also accepts a negated form (--no-<name> via InversePrefix, default "no-"). During Set, if the positive form (Name or an alias) is being applied but the negative form was already set (bif.nset), the library refuses to apply both, since a bool cannot be simultaneously true and false. This is thrown from the positive-set branch of BoolWithInverseFlag.Set.

Source

Thrown at flag_bool_with_inverse.go:126

			}

			bif.hasBeenSet = true
		}
	}

	return nil
}

func (bif *BoolWithInverseFlag) Set(name, val string) error {
	if bif.count > 0 && bif.OnlyOnce {
		return fmt.Errorf("can't duplicate this flag")
	}

	bif.hasBeenSet = true

	if slices.Contains(append([]string{bif.Name}, bif.Aliases...), name) {
		if bif.nset {
			return fmt.Errorf("cannot set both flags `--%s` and `--%s`", bif.Name, bif.inversePrefix()+bif.Name)
		}
		if err := bif.value.Set(val); err != nil {
			return err
		}
		bif.pset = true
	} else {
		if bif.pset {
			return fmt.Errorf("cannot set both flags `--%s` and `--%s`", bif.Name, bif.inversePrefix()+bif.Name)
		}
		if err := bif.value.Set("false"); err != nil {
			return err
		}
		bif.nset = true
	}

	if bif.Validator != nil {
		return bif.Validator(bif.value.Get().(bool))
	}

View on GitHub (pinned to 1a4deb4f5a)

Solutions

  1. Remove one of the two conflicting flags from the command line — keep either --name or --no-name, not both.
  2. Check the flag's Sources (env vars, config files) to make sure an external source is not already setting the inverse form before the CLI argument is applied.
  3. If both forms must be tolerated, use a plain BoolFlag instead of BoolWithInverseFlag, which has no mutual-exclusion check.
  4. Inspect scripts/aliases that prepend flags (e.g. a Makefile or wrapper adding --no-X) and reconcile with user-supplied flags.

Example fix

// before
myapp --verbose --no-verbose

// after
myapp --verbose   # or: myapp --no-verbose
Defensive patterns

Strategy: validation

Validate before calling

// shell pre-check before invoking the app
args=("$@")
pos=$(printf '%s\n' "${args[@]}" | grep -c -- '--verbose$' || true)
neg=$(printf '%s\n' "${args[@]}" | grep -c -- '--no-verbose$' || true)
if [ "$pos" -gt 0 ] && [ "$neg" -gt 0 ]; then echo "conflict: use --verbose OR --no-verbose" >&2; exit 1; fi

Try / catch

if err := cmd.Run(ctx, os.Args); err != nil {
    if strings.Contains(err.Error(), "cannot set both flags") {
        fmt.Fprintln(os.Stderr, "conflicting bool flag forms; pick one of --name / --no-name")
        os.Exit(2)
    }
    return err
}

Prevention

When it happens

Trigger: The user passes both the positive and negative forms on the command line, e.g. `--verbose --no-verbose`, or an alias plus the negated name (e.g. `--v --no-verbose`). Also occurs when a source (env/file via Sources) sets the inverse value first and then the positive flag is parsed, since PostParse calls Set for external sources too.

Common situations: Shell aliases or wrapper scripts that append --no-X while the user also types --X; conflicting environment variables resolved through Sources; copy-pasted command lines where a negation was left in accidentally.

Related errors


AI-assisted analysis of urfave/cli@1a4deb4f5a (2026-08-31). Data as JSON: /api/errors/ab3e029ee85ce7e3. Report an issue: GitHub.