ruby/ruby · error · Bundler::InvalidOption

15

15

Error message

You cannot specify `--branch` and `--ref` at the same time.

What it means

Raised as Bundler::InvalidOption by Bundler::Plugin.install before the installer runs, when the options hash (string keys, as the CLI passes them) has truthy values for both "branch" and "ref". It is a fast-fail duplicate of the installer-level consistency check for a request that can never be satisfied: one git checkout cannot honor two different pins.

Source

Thrown at lib/bundler/plugin.rb:49

    def reset!
      instance_variables.each {|i| remove_instance_variable(i) }

      @sources = {}
      @commands = {}
      @hooks_by_event = Hash.new {|h, k| h[k] = [] }
      @loaded_plugin_names = []
      @index = nil
    end

    reset!

    # Installs a new plugin by the given name
    #
    # @param [Array<String>] names the name of plugin to be installed
    # @param [Hash] options various parameters as described in description.
    #               Refer to cli/plugin for available options
    def install(names, options)
      raise InvalidOption, "You cannot specify `--branch` and `--ref` at the same time." if options["branch"] && options["ref"]

      specs = Installer.new.install(names, options)

      save_plugins specs.slice(*names)
    rescue PluginError
      specs_to_delete = specs.select {|k, _v| names.include?(k) && !index.commands.values.include?(k) }
      specs_to_delete.each_value {|spec| Bundler.rm_rf(spec.full_gem_path) }

      raise
    end

    # Uninstalls plugins by the given names
    #
    # @param [Array<String>] names the names of plugins to be uninstalled
    def uninstall(names, options)
      if names.empty? && !options[:all]
        Bundler.ui.error "No plugins to uninstall. Specify at least 1 plugin to uninstall.\n"\
          "Use --all option to uninstall all the installed plugins."

View on GitHub (pinned to 0e5b888e1c)

Solutions

  1. Keep only one pinning flag: --branch (moving branch) or --ref (fixed revision), never both
  2. Re-run with a single pin: `bundle plugin install my-plugin --git <url> --ref <sha>`

Example fix

# before
bundle plugin install my-plugin --git https://github.com/org/my-plugin.git --branch main --ref abc123
# after
bundle plugin install my-plugin --git https://github.com/org/my-plugin.git --branch main
Defensive patterns

Strategy: validation

Validate before calling

# CLI-style string keys, as Bundler::Plugin.install receives them
raise ArgumentError, "branch and ref are mutually exclusive" if opts["branch"] && opts["ref"]
Bundler::Plugin.install(names, opts)

Try / catch

begin
  Bundler::Plugin.install(names, "git" => url, "branch" => "main")
rescue Bundler::InvalidOption => e
  abort "#{e.message}" # re-prompt the user for a single pin
end

Prevention

When it happens

Trigger: `bundle plugin install my-plugin --git https://... --branch main --ref abc123` — the CLI forwards both flags, and Plugin#install raises immediately since options["branch"] && options["ref"] is true.

Common situations: Scripts that template all pinning flags into one command; shell history editing that appends --ref after --branch without deleting it; documentation examples that show both flags together.

Related errors


AI-assisted analysis of ruby/ruby@0e5b888e1c (2026-08-21). Data as JSON: /api/errors/e3dd99e9653cff3e. Report an issue: GitHub.