{"record":{"id":"1c689d21951a5198","repo":"gitbutlerapp/gitbutler","slug":"infinite-loop-should-find-a-unique-name","errorCode":null,"errorMessage":"infinite loop should find a unique name","messagePattern":"infinite loop should find a unique name","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"info","filePath":"crates/but-core/src/branch/generate.rs","lineNumber":84,"sourceCode":"        .category()\n        .with_context(|| format!(\"Input branch {template} could not be categorized\"))?;\n    let mut candidate_short = BString::default();\n    for num in start_num.. {\n        candidate_short.clear();\n        candidate_short.push_str(base);\n        candidate_short.push(b'-');\n        candidate_short.push_str(num.to_string());\n\n        if rtb_lut.contains(candidate_short.as_bstr()) {\n            continue;\n        }\n        let candidate_full = category.to_full_name(candidate_short.as_bstr())?;\n\n        if repo.try_find_reference(&candidate_full)?.is_none() {\n            return Ok(candidate_full);\n        }\n    }\n    unreachable!(\"infinite loop should find a unique name\")\n}\n\n/// Find a new unique branch name, one that doesn't exist in `repo` yet.\n///\n/// See caveats of [`find_unique_refname()`].\npub fn unique_canned_refname(repo: &gix::Repository) -> anyhow::Result<gix::refs::FullName> {\n    let name = canned_refname(repo)?;\n    find_unique_refname(repo, name.as_ref())\n}\n\nfn generate_short_name_from_signature(author: &gix::actor::Signature) -> anyhow::Result<BString> {\n    let name = author.name.to_str_lossy();\n    // Split by whitespace to get words\n    let words: Vec<&str> = name.split_whitespace().collect();\n\n    // Try to extract initials from words\n    let prefix: Vec<&str> = words\n        .iter()","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but-core/src/branch/generate.rs#L66-L102","documentation":"`find_unique_refname` (but-core/src/branch/generate.rs:31) walks `for num in start_num..` trying `base-{num}` against remote-tracking short names and existing references, returning on the first free candidate. Because `start_num..` is an infinite `usize` range whose only exits are the two `return`s, the trailing `unreachable!` is a compiler-satisfying marker, not a reachable error path; it could only execute after exhausting every `usize` value (or via arithmetic overflow, which panics on its own first).","triggerScenarios":"Practically untriggerable: it would require a repository containing every suffix from `start_num` up to `usize::MAX`. Debug-build overflow of `num` panics earlier with an arithmetic message instead.","commonSituations":"None in practice; the string mostly shows up in code review, static analysis, or crash-aggregation greps rather than real traces.","solutions":["Treat any sighting as a signal of memory corruption or a forged repository state, and capture a core dump / report upstream.","If you must bound it defensively, convert the loop to a `while num != usize::MAX` with an explicit error return after the bound.","Do not 'fix' it by removing the return paths; they are the normal exits."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Recognize this as a dead-code marker: the for-loop over an infinite range only exits via return.","Any real occurrence implies memory corruption or a hostile repo — capture a core dump and report it rather than 'fixing' the line.","Keep the two early returns (template free, candidate free) intact when refactoring the naming loop."],"tags":["rust","but-core","branch-naming","unreachable","dead-code-marker"],"backgroundTag":"unique-name-generation-exhausted","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}