{"record":{"id":"6d5e752b775cb364","repo":"gitbutlerapp/gitbutler","slug":"repository-path-is-not-valid-utf-8","errorCode":null,"errorMessage":"Repository path is not valid UTF-8","messagePattern":"Repository path is not valid UTF-8","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but/src/command/legacy/setup.rs","lineNumber":540,"sourceCode":"            .remote_default_name(gix::remote::Direction::Push)\n            .is_none()\n    {\n        anyhow::bail!(\n            \"Neither found push remote found in workspace nor unambiguously in the Git repository configuration.\"\n        )\n    };\n\n    Ok(true)\n}\n\n/// Creates a 'gb-local' remote pointing to this repository and creates tracking refs for the default branch.\nfn setup_local_remote(repo: &gix::Repository, out: &mut OutputChannel) -> anyhow::Result<String> {\n    let t = theme::get();\n    let repo_url = repo\n        .workdir()\n        .ok_or_else(|| anyhow::anyhow!(\"Repository has no working directory\"))?\n        .to_str()\n        .ok_or_else(|| anyhow::anyhow!(\"Repository path is not valid UTF-8\"))?;\n\n    if let Some(out) = out.for_human() {\n        writeln!(\n            out,\n            \"  {}\",\n            t.info\n                .paint(\"No push remote found, creating gb-local remote...\")\n        )?;\n    }\n\n    edit_repo_config(repo, gix::config::Source::Local, |config| {\n        let mut section = config.section_mut_or_create_new(\"remote\", Some(\"gb-local\".into()))?;\n        section.push(\"url\", repo_url)?;\n        Ok(())\n    })?;\n\n    // Figure out what local branch is probably the default target\n    let mut head_ref = repo.head()?;","sourceCodeStart":522,"sourceCodeEnd":558,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but/src/command/legacy/setup.rs#L522-L558","documentation":"Thrown by `setup_local_remote` on the gb-local fallback path: `repo.workdir()` exists, but converting the path to a string with `to_str()` fails because the path contains bytes that are not valid UTF-8. Rust `Path::to_str` returns None for such paths, and the remote URL must be a String, so setup aborts before writing the remote config.","triggerScenarios":"The repository lives under a directory whose name has non-UTF-8 bytes (e.g. legacy Latin-1 encoded names on Unix), and setup runs with no push remote configured so `gb-local` URL construction is attempted.","commonSituations":"Older Unix filesystems with non-UTF-8 locale encodings; archives or tools that materialized byte-escaped directory names; names containing unpaired surrogate-ish byte sequences from mis-decompressed data.","solutions":["Move or rename the repository to a path that is valid UTF-8 (`mv` with a fresh typed name), then rerun setup","Add a push remote so the gb-local fallback (which needs the UTF-8 URL) is skipped entirely","Alternatively create a UTF-8 symlink to the repo directory and run setup through the symlink path"],"exampleFix":"# before: path has invalid bytes\ncd $'~/work/proj\\xff' && but setup\n\n# after: rename to a UTF-8 path\nmv $'~/work/proj\\xff' ~/work/project\nbut setup ~/work/project","handlingStrategy":"validation","validationCode":"let Some(url) = repo.workdir().and_then(|p| p.to_str()) else {\n    anyhow::bail!(\"repo path is not valid UTF-8; rename the directory or add a push remote\");\n};\n// safe to build the gb-local URL from `url`","typeGuard":null,"tryCatchPattern":"match setup_local_remote(&repo, &mut out) {\n    Ok(remote) => { /* use remote */ }\n    Err(err) if err.to_string().contains(\"not valid UTF-8\") => {\n        // move repo to a UTF-8 path or configure a push remote\n    }\n    Err(err) => return Err(err),\n}","preventionTips":["Keep repositories under UTF-8 paths; rename legacy-encoded directories","Add a push remote to skip the gb-local URL construction entirely","Symlink from an ASCII/UTF-8 path when renaming is not an option"],"tags":["rust","cli","setup","filesystem","unicode","git-remote"],"backgroundTag":"non-utf8-path","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}