GitoxideLabs/gitoxide · error
no illformed UTF-8
Error message
no illformed UTF-8
What it means
The second expect in `worktree::Proxy::id()`: `os_str_into_bstr(...).expect("no illformed UTF-8")` panics when the worktree directory name cannot be represented as UTF-8-backed bytes. On Unix this means the directory name contains invalid UTF-8; on Windows, non-representable wide characters per the conversion rules.
Solutions
- Rename the worktree directory to a valid UTF-8 name (prefer `git worktree add` with ASCII names).
- Validate the name: check `file_name().to_str().is_some()` before invoking worktree APIs.
- Normalize tooling/locales that create worktrees so names are always UTF-8.
Example fix
// before
let id = proxy.id(); // panics on non-UTF-8 dir name
// after
let name = proxy.git_dir().file_name().and_then(|n| n.to_str());
if name.is_none() { eprintln!("worktree name is not valid UTF-8"); return; }
let id = proxy.id(); Defensive patterns
Strategy: validation
Validate before calling
let ok = proxy.git_dir().file_name().map_or(false, |n| n.to_str().is_some());
if !ok { return Err(anyhow::anyhow!("worktree name must be valid UTF-8")); }
Type guard
fn utf8_named(p: &std::path::Path) -> bool { p.file_name().map_or(false, |n| n.to_str().is_some()) }
Prevention
- Validate worktree names are UTF-8 at creation time
- Avoid non-UTF-8 locales/scripts when creating worktrees
- Prefer plain-ASCII worktree names for portability
When it happens
Trigger: Calling `worktree::Proxy::id()` when the worktree's directory name under `worktrees/` contains non-UTF-8 bytes or unencodable characters.
Common situations: Linux filesystems allowing arbitrary bytes in names; worktrees created by non-UTF-8-aware scripts or third-party tools; locale mismatch when creating worktrees.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- no illformed UTF-8
- Illformed UTF-8
- shell assignment names contain only ASCII bytes
- at least one directory level
- worktrees/ parent dir
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/37ca782f83c0f4d4.
Report an issue: GitHub.
Appendix: source
Thrown at gix/src/worktree/proxy.rs:70
)
})?
}
/// Read the location of the checkout, the base of the work tree.
/// Note that the location might not exist.
pub fn base(&self) -> std::io::Result<PathBuf> {
Ok(gix_discover::path::without_dot_git_dir(self.dot_git()?))
}
/// The git directory for the work tree, typically contained within the parent git dir.
pub fn git_dir(&self) -> &Path {
&self.git_dir
}
/// The name of the worktree, which is derived from its folder within the `worktrees` directory within the parent `.git` folder.
pub fn id(&self) -> &BStr {
gix_path::os_str_into_bstr(self.git_dir.file_name().expect("worktrees/ parent dir"))
.expect("no illformed UTF-8")
}
/// Return true if the worktree cannot be pruned, moved or deleted, which is useful if it is located on an external storage device.
pub fn is_locked(&self) -> bool {
self.git_dir.join("locked").symlink_metadata().is_ok()
}
/// Return true if this worktree can be pruned without an expiry grace period.
///
/// Locked worktrees are never prunable. Otherwise, an unreadable `gitdir` file or missing target
/// makes the worktree prunable.
pub fn is_prunable(&self) -> bool {
!self.is_locked()
&& self
.dot_git()
.map_or(true, |dot_git| dot_git.symlink_metadata().is_err())
}
View on GitHub (pinned to e73179060b)