gitbutlerapp/gitbutler · error

Too many arguments. Usage: but-installer [version|nightly] o

Error message

Too many arguments. Usage: but-installer [version|nightly] or GITBUTLER_VERSION=<version> but-installer

What it means

but-installer's InstallerConfig::new() (crates/but-installer/src/config.rs:127-134) accepts at most one positional argument: a semver version or the literal 'nightly'. It bails as soon as env::args() yields more than two entries (argv[0] plus one positional), because there is no way to decide which extra argument is the intended version. Flags like --help or -v are rejected here too, before VersionRequest::from_string() ever sees them.

Source

Thrown at crates/but-installer/src/config.rs:131

            }
        }
    }
}

/// Configuration for the installer
pub struct InstallerConfig {
    pub version_request: VersionRequest,
    pub home_dir: PathBuf,
    pub platform: String,
}

impl InstallerConfig {
    /// Create a new installer config, reading version from command-line arguments or environment
    pub fn new() -> Result<Self> {
        // Validate argument count - only 0 or 1 positional arguments allowed
        let args: Vec<String> = env::args().collect();
        if args.len() > 2 {
            bail!(
                "Too many arguments. Usage: but-installer [version|nightly] or GITBUTLER_VERSION=<version> but-installer"
            );
        }

        // Get version from CLI argument (takes precedence) or GITBUTLER_VERSION env var
        let version_string = args
            .get(1)
            .cloned()
            .or_else(|| env::var("GITBUTLER_VERSION").ok());

        let version_request = VersionRequest::from_string(version_string)?;
        Self::new_with_version(version_request)
    }

    /// Create a new installer config with an explicit version request
    pub(crate) fn new_with_version(version_request: VersionRequest) -> Result<Self> {
        let home_dir =
            dirs::home_dir().ok_or_else(|| anyhow!("Failed to determine home directory"))?;

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Pass at most one positional argument: a version like 0.18.7 or the literal nightly
  2. Set the version via environment instead: GITBUTLER_VERSION=<version> but-installer
  3. If embedding the library, call run_installation_with_version(VersionRequest::Specific(...), interactive) so argv is never parsed
  4. Filter flags and extra arguments out in wrapper scripts before invoking but-installer

Example fix

# before
but-installer 0.18.7 nightly
# after
GITBUTLER_VERSION=0.18.7 but-installer
Defensive patterns

Strategy: validation

Validate before calling

// Guard argv before calling run_installation(), which parses process args
let args: Vec<String> = std::env::args().collect();
if args.len() > 2 {
    eprintln!("Usage: {} [version|nightly] or GITBUTLER_VERSION=<version>", args[0]);
    std::process::exit(2);
}
but_installer::run_installation()?;

Try / catch

if let Err(e) = but_installer::run_installation() {
    if e.to_string().contains("Too many arguments") {
        eprintln!("Usage: but-installer [version|nightly] or GITBUTLER_VERSION=<version> but-installer");
        std::process::exit(2);
    }
    return Err(e);
}

Prevention

When it happens

Trigger: Invoking the installer binary produced by this crate with two or more positional arguments: 'but-installer 0.18.7 nightly', 'but-installer --version 1.2.3', or any wrapper script that forwards "$@" or appends flags to the installer process before calling run_installation().

Common situations: Users assuming the installer takes flags (--help/--version); curl|sh wrapper scripts forwarding extra shell arguments; CI jobs appending parameters to the install command line.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/daa9dc6bd5d1f8df. Report an issue: GitHub.