GitoxideLabs/gitoxide · error
Illformed UTF-8
Error message
Illformed UTF-8
What it means
`TryFrom<OsString> for Boolean` first converts the OS string into a `&BStr` via `gix_path::os_str_into_bstr`; when that conversion fails (the OS string is not representable as the byte string form, e.g. non-UTF-8 path-like data on some platforms) the code raises this Error labeled 'Illformed UTF-8' with the display form of the original value. It is a pre-parse failure, before boolean syntax is even examined.
Solutions
- Sanitize or reject non-UTF-8 input before calling `Boolean::try_from(OsString)`
- Convert the input to a `&BStr` yourself from known-good bytes (`BStr::new(&bytes)`) and use the `TryFrom<&BStr>` path
- Catch the Error and report which value was ill-formed to the user
Example fix
// before
let b = Boolean::try_from(os_value)?;
// after
let b = match std::str::from_utf8(os_value.as_bytes()) {
Ok(s) => Boolean::try_from(BStr::new(s))?,
Err(_) => return Err(/* report ill-formed UTF-8 input */),
}; Defensive patterns
Strategy: type-guard
Validate before calling
std::str::from_utf8(os_value.as_bytes()).map_err(|_| /* ill-formed UTF-8 */)?;
Type guard
fn is_utf8(v: &OsStr) -> bool { std::str::from_utf8(v.as_bytes()).is_ok() } Try / catch
match Boolean::try_from(os_value) { Ok(b) => b, Err(e) => { log::warn!("invalid boolean input: {e}"); Boolean::default() } } Prevention
- Reject non-UTF-8 inputs at the boundary (CLI/env) before they reach config parsing
- Convert to BStr from trusted bytes when the source encoding is known
- Log the offending input for diagnostics
When it happens
Trigger: `Boolean::try_from(os_string)` where `os_string` comes from an environment variable, command-line argument, or file path that contains bytes that cannot be converted (e.g. non-UTF-8 Windows/OsStr data).
Common situations: Config values sourced from raw OS strings on platforms where `OsStr` is not UTF-8 internally (Windows WTF-16), or shell arguments containing invalid UTF-8 bytes.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- no illformed UTF-8
- no illformed UTF-8
- The remote has no URL
- Without refspecs there is nothing to show here. Add…
- CommentChar must not contain a line ending
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/63ff670cfc965fee.
Report an issue: GitHub.
Appendix: source
Thrown at gix-config-value/src/boolean.rs:19
use std::{borrow::Cow, ffi::OsString, fmt::Display};
use bstr::{BStr, BString, ByteSlice};
use crate::{Boolean, Error};
fn bool_err(input: impl Into<BString>) -> Error {
Error::new(
"Booleans need to be 'no', 'off', 'false', '' or 'yes', 'on', 'true' or any number",
input,
)
}
impl TryFrom<OsString> for Boolean {
type Error = Error;
fn try_from(value: OsString) -> Result<Self, Self::Error> {
let value = gix_path::os_str_into_bstr(&value)
.map_err(|_| Error::new("Illformed UTF-8", std::path::Path::new(&value).display().to_string()))?;
Self::try_from(value)
}
}
/// # Warning
///
/// The direct usage of `try_from("string")` is discouraged as it will produce the wrong result for values
/// obtained from `core.bool-implicit-true`, which have no separator and are implicitly true.
/// This method chooses to work correctly for `core.bool-empty=`, which is an empty string and resolves
/// to being `false`.
///
/// Instead of this, obtain booleans with `config.boolean(…)`, which handles the case were no separator is
/// present correctly.
impl TryFrom<&BStr> for Boolean {
type Error = Error;
fn try_from(value: &BStr) -> Result<Self, Self::Error> {
if parse_true(value) {View on GitHub (pinned to e73179060b)