gitbutlerapp/gitbutler · error

BUG: value must be valid ref name

Error message

BUG: value must be valid ref name

What it means

BranchIdentity implements From<&str> by parsing the string as a gix::refs::PartialName and expects success. The impl is documented as test-only convenience: it panics if the value is not a valid partial ref name. Production code should use TryFrom<&BStr> which returns gix::refs::name::Error instead.

Solutions

  1. Validate the branch name before conversion, or use TryFrom<&BStr> for BranchIdentity and handle the error
  2. Restrict From<&str> usage to tests; in application code accept BranchIdentity only via fallible conversions
  3. Sanitize user input into a valid git ref name (e.g. via gix validate) before building a BranchIdentity

Example fix

// before
let identity = BranchIdentity::from(user_branch_name); // panics on invalid name
// after
let identity = BranchIdentity::try_from(gix::bstr::ByteSlice::as_bstr(user_branch_name.as_bytes()))
    .context("invalid branch name")?;
Defensive patterns

Strategy: validation

Validate before calling

// Rust: validate before conversion
fn is_valid_partial_name(value: &str) -> bool {
    gix::refs::PartialName::try_from(value).is_ok()
}

Type guard

fn try_branch_identity(value: &str) -> Option<BranchIdentity> {
    gix::refs::PartialName::try_from(value).ok().map(BranchIdentity)
}

Try / catch

// Panics cannot be caught idiomatically in Rust; prefer the fallible API:
let identity = BranchIdentity::try_from(gix::bstr::BStr::new(value))
    .map_err(|e| anyhow::anyhow!("invalid branch name {value:?}: {e}"))?;

Prevention

When it happens

Trigger: Constructing a BranchIdentity from a &str containing characters or formatting invalid for a git partial ref name (e.g. spaces, leading dots, '..' sequences, empty string).

Common situations: Tests using convenient string literals (intended use), or accidental production use of the From impl with user-supplied branch names that aren't valid ref names.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/b797556ffcfc1a6c. Report an issue: GitHub.

Appendix: source

Thrown at crates/gitbutler-branch/src/branch.rs:68

        self.0.as_ref().as_bstr()
    }
}

/// Facilitate obtaining this type from the UI.
impl TryFrom<String> for BranchIdentity {
    type Error = gix::refs::name::Error;

    fn try_from(value: String) -> std::result::Result<Self, Self::Error> {
        gix::refs::PartialName::try_from(value).map(BranchIdentity)
    }
}

/// Used in testing, and **panics** if the value isn't a valid partial ref name
impl From<&str> for BranchIdentity {
    fn from(value: &str) -> Self {
        gix::refs::PartialName::try_from(value)
            .map(BranchIdentity)
            .expect("BUG: value must be valid ref name")
    }
}

/// Used in for short-name conversions
impl TryFrom<&BStr> for BranchIdentity {
    type Error = gix::refs::name::Error;

    fn try_from(value: &BStr) -> std::result::Result<Self, Self::Error> {
        gix::refs::PartialName::try_from(value.to_owned()).map(BranchIdentity)
    }
}

impl std::fmt::Display for BranchIdentity {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.0.as_ref().as_bstr().to_str_lossy())
    }
}

View on GitHub (pinned to 58e5313667)