gitbutlerapp/gitbutler · error

Invalid version: empty string. Usage: but-installer [version

Error message

Invalid version: empty string. Usage: but-installer [version|nightly]

What it means

Thrown by but-installer's Version::validate (crates/but-installer/src/config.rs:47) when the version argument is an empty string. Version::new validates before constructing, so an empty input never becomes a Version value. In practice this almost always means a wrapper script passed an unset/empty shell variable ($1 missing) rather than a user literally typing nothing.

Source

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

/// - Contains at least one alphanumeric character
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Version(String);

impl Version {
    /// Create a new Version from a string, validating the format.
    ///
    /// # Errors
    /// Returns an error if the version string is invalid.
    pub fn new(version: String) -> Result<Self> {
        Self::validate(&version)?;
        Ok(Version(version))
    }

    /// Validate a version string format
    fn validate(version: &str) -> Result<()> {
        // Reject empty strings
        if version.is_empty() {
            bail!("Invalid version: empty string. Usage: but-installer [version|nightly]");
        }

        // Reject if it looks like a flag
        if version.starts_with('-') {
            bail!("Invalid version: {version}. Usage: but-installer [version|nightly]");
        }

        // Only allow semver-compatible characters
        if !version
            .chars()
            .all(|c| c.is_alphanumeric() || c == '.' || c == '-' || c == '+')
        {
            bail!(
                "Invalid version format: {version}. Version must contain only alphanumeric characters, dots, hyphens, and plus signs."
            );
        }

        // Must contain at least one alphanumeric character

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Pass an explicit version (`but-installer 1.2.3`) or the literal `nightly`
  2. In scripts, default the variable: `but-installer "${VERSION:-nightly}"`
  3. In CI, guard empty inputs before the call or set a fallback value on the variable

Example fix

# before
but-installer "$VERSION"   # VERSION unset -> empty string -> error

# after
but-installer "${VERSION:-nightly}"
Defensive patterns

Strategy: validation

Validate before calling

let version = std::env::args().nth(1).unwrap_or_default();
if version.is_empty() {
    eprintln!("no version given; defaulting to nightly");
    // or: std::process::exit(2);
}
let v = Version::new(if version.is_empty() { "nightly".to_string() } else { version })?;

Type guard

fn non_empty_version(v: &str) -> bool { !v.is_empty() }

Try / catch

if let Err(err) = Version::new(version) {
    if err.to_string().contains("empty string") { eprintln!("usage: but-installer [version|nightly]"); std::process::exit(2); }
    return Err(err);
}

Prevention

When it happens

Trigger: Running `but-installer ""` ; a shell script invoking `but-installer $VERSION` with VERSION unset and the word-splitting leaving an empty arg; CI passing an empty matrix variable.

Common situations: Installer wrapper scripts that forward "$1" without a default; CI jobs with an optional version input that resolves to empty; typos in automation (env var name mismatch yields '').

Related errors


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