gitbutlerapp/gitbutler · error

Invalid version format: {version}. Version must contain only

Error message

Invalid version format: {version}. Version must contain only alphanumeric characters, dots, hyphens, and plus signs.

What it means

Thrown by but-installer's Version::validate (crates/but-installer/src/config.rs:60) when the version string contains characters outside [A-Za-z0-9.+-] — e.g., underscores, spaces, slashes, 'v' is fine but '1.2.3_beta!' or 'rel/1.2.3' are not. The check is charset-based only (it does not verify semver structure), and runs after the empty-string and leading-dash checks.

Source

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

    /// 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
        if !version.chars().any(|c| c.is_alphanumeric()) {
            bail!(
                "Invalid version format: {version}. Version must contain at least one alphanumeric character."
            );
        }

        Ok(())
    }

    /// Get the version string as a &str
    pub fn as_str(&self) -> &str {
        &self.0
    }

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Strip or replace offending characters: underscores → hyphens, remove '/' and spaces (e.g., v1.2.3-beta.1)
  2. Use the exact tag name from the releases page, dropping any namespace prefix
  3. In scripts, sanitize: `VERSION=$(echo "$TAG" | tr '/_' '--')`

Example fix

# before
but-installer "release/1.2.3_beta"   # '/' and '_' rejected

# after
but-installer "1.2.3-beta"           # only alphanumerics, '.', '-', '+'
Defensive patterns

Strategy: validation

Validate before calling

fn valid_version_charset(v: &str) -> bool {
    !v.is_empty() && !v.starts_with('-')
        && v.chars().all(|c| c.is_alphanumeric() || matches!(c, '.' | '-' | '+'))
        && v.chars().any(|c| c.is_alphanumeric())
}
ensure!(valid_version_charset(&version), "version may only contain [A-Za-z0-9.+-]");
let v = Version::new(version)?;

Type guard

fn is_installable_version(v: &str) -> bool {
    v.chars().all(|c| c.is_alphanumeric() || matches!(c, '.' | '-' | '+'))
        && v.chars().any(|c| c.is_alphanumeric())
        && !v.starts_with('-')
}

Try / catch

if let Err(err) = Version::new(version) {
    if err.to_string().contains("must contain only alphanumeric") {
        eprintln!("clean the version string: allowed chars are letters, digits, '.', '-', '+'");
        std::process::exit(2);
    }
    return Err(err);
}

Prevention

When it happens

Trigger: Passing a git tag verbatim that contains '/', '_' or other symbols (e.g., `but-installer v1.2.3-beta_1` or `but-installer release/2024.1`); copy-paste artifacts like whitespace or quotes; Windows-style version strings with parentheses.

Common situations: Version strings sourced from branch names or tags with slashes; prerelease labels using underscores instead of hyphens; invisible characters pasted from release notes.

Related errors


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