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
- Strip or replace offending characters: underscores → hyphens, remove '/' and spaces (e.g., v1.2.3-beta.1)
- Use the exact tag name from the releases page, dropping any namespace prefix
- 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
- Convert '_' to '-' in prerelease labels; drop '/' namespaces from tag-based versions
- Sanitize in scripts: VERSION=$(printf '%s' "$TAG" | tr '/_' '--') before invoking the installer
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
- Invalid version: empty string. Usage: but-installer [version
- Invalid version format: {version}. Version must contain at l
- Invalid version: {version}. Usage: but-installer [version|ni
- Too many arguments. Usage: but-installer [version|nightly] o
- valid hex prefix
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/e1c8ef7a5b25bf4f.
Report an issue: GitHub.