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 characterView on GitHub (pinned to caf1f223d3)
Solutions
- Pass an explicit version (`but-installer 1.2.3`) or the literal `nightly`
- In scripts, default the variable: `but-installer "${VERSION:-nightly}"`
- 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
- Default unset variables in scripts: but-installer "${VERSION:-nightly}"
- Quote shell expansions so empty variables are visible instead of vanishing
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
- Invalid version format: {version}. Version must contain only
- 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/cde711322ebc6d8d.
Report an issue: GitHub.