GitoxideLabs/gitoxide · error
shell assignment names contain only ASCII bytes
Error message
shell assignment names contain only ASCII bytes
What it means
After an assignment separator is found, the variable NAME portion is decoded as UTF-8 and the code asserts shell assignment names are pure ASCII. A non-UTF8/ASCII byte in the assignment name (e.g. from odd shell quoting or binary content before `=`) panics instead of producing an error.
Solutions
- Ensure environment variable names in the command string are ASCII (standard for POSIX shells anyway)
- Sanitize or validate the command string bytes before parsing
- Handle it upstream: split assignments yourself and pass env explicitly via Outcome/env APIs
- File a bug requesting a graceful error instead of a panic for non-ASCII names
Example fix
// before
String::from_utf8(word.value[..separator].to_owned())
.expect("shell assignment names contain only ASCII bytes")
// after
String::from_utf8(word.value[..separator].to_owned())
.map_err(|_| Error::InvalidAssignmentName)? Defensive patterns
Strategy: validation
Validate before calling
// Ensure assignment names are ASCII before parsing:
fn ascii_names_ok(cmd: &[u8]) -> bool {
cmd.split(|b| *b == b'=').next()
.map(|name| name.is_ascii() && !name.is_empty())
.unwrap_or(false)
} Type guard
fn is_ascii_name(name: &[u8]) -> bool { !name.is_empty() && name.iter().all(|b| b.is_ascii_alphanumeric() || *b == b'_') } Prevention
- Keep environment variable names ASCII
- Normalize encodings before passing command strings on non-UTF8 filesystems
- Prefer passing env via explicit maps rather than inline assignments
- Validate command strings in tests with non-ASCII fixtures
When it happens
Trigger: Parsing a command line whose environment assignment name (the text before `=`) contains non-ASCII or invalid UTF-8 bytes, e.g. `VÄR=1 cmd` passed as raw bytes.
Common situations: Locale/encoding mismatches when building command strings on non-UTF8 filesystems; scripts embedding non-ASCII variable names; byte-level manipulation of command strings.
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
- no illformed UTF-8
- Illformed UTF-8
- only recognized assignments remain
- io::sink() to never fail
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/47bb6d5862d03e88.
Report an issue: GitHub.
Appendix: source
Thrown at gix-command/src/parse.rs:78
/// expansions and operators are not interpreted. An assignment is recognized only when its name is an unquoted
/// shell identifier. Assignment-only input is rejected because it contains no command to execute. Environment
/// assignment names are strings, while their values, the command, and arguments are converted losslessly to OS
/// strings or rejected if the platform cannot represent them.
pub fn command_line(input: &BStr) -> Result<Outcome, Error> {
let mut words = parse_words(input)?;
let assignment_count = words
.iter()
.take_while(|word| word.assignment_separator.is_some())
.count();
let mut args = words.split_off(assignment_count).into_iter().map(|word| word.value);
let command = into_os_string(args.next().ok_or(Error::MissingCommand)?)?;
let env = words
.into_iter()
.map(|word| {
let separator = word.assignment_separator.expect("only recognized assignments remain");
Ok((
String::from_utf8(word.value[..separator].to_owned())
.expect("shell assignment names contain only ASCII bytes"),
into_os_string(word.value[separator + 1..].to_owned().into())?,
))
})
.collect::<Result<_, Error>>()?;
Ok(Outcome {
env,
command,
args: args.map(into_os_string).collect::<Result<_, _>>()?,
})
}
pub(crate) fn arguments(input: &BStr) -> Result<Vec<OsString>, Error> {
parse_words(input)?
.into_iter()
.map(|word| into_os_string(word.value))
.collect()
}
View on GitHub (pinned to e73179060b)