jdx/mise · error
the prefix cannot be printed as a single UTF-8 path; use a…
Error message
the prefix cannot be printed as a single UTF-8 path; use a compatible prefix path
What it means
strict_package_root validates the `opt/<name>` record for an installed brew formula. It first checks that MISE_SYSTEM_BREW_PREFIX, when set, is representable as UTF-8, because the prefix path must be printable and passed to subprocesses/paths as a Rust str-backed Path. If the environment variable contains bytes that are not valid UTF-8 (e.g. invalid UTF-8 from a shell env), mise bails instead of guessing an encoding.
Solutions
- Unset or correct MISE_SYSTEM_BREW_PREFIX so it contains a valid UTF-8 absolute path (e.g. /home/linuxbrew/.linuxbrew)
- Print the variable to check it: `printf '%s' "$MISE_SYSTEM_BREW_PREFIX" | iconv -f utf-8 -t utf-8` — failure confirms invalid bytes
- Remove the override entirely to let mise use the default prefix
Example fix
// before export MISE_SYSTEM_BREW_PREFIX=$'\xff/home/brew' # invalid UTF-8 // after export MISE_SYSTEM_BREW_PREFIX=/home/linuxbrew/.linuxbrew
Defensive patterns
Strategy: validation
Validate before calling
if (process.env.MISE_SYSTEM_BREW_PREFIX !== undefined) {
Buffer.from(process.env.MISE_SYSTEM_BREW_PREFIX, 'utf8'); // throws on invalid encoding
} Prevention
- Set MISE_SYSTEM_BREW_PREFIX from a literal or command substitution of a plain path
- Verify env exports in provisioning scripts don't capture binary output
- Keep provisioning scripts in UTF-8-safe shells/locales
When it happens
Trigger: Setting MISE_SYSTEM_BREW_PREFIX to a value with non-UTF-8 bytes (e.g. via `env -i` scripts, raw byte export, or copy-pasted control characters) and then invoking anything that calls strict_package_root to resolve a package root.
Common situations: Container/CI images exporting env vars built from binary data; shells with locale mishandling producing invalid UTF-8 paths; accidentally setting the variable to a command's binary output.
Understand the failure class
Background: "is not a valid" / "Invalid ... value" environment variable errors: how libraries validate env vars and what to do when they reject yours — this error's family across 48 libraries.
Related errors
- brew-cask: invalid command_wrapper environment name
- app Info.plist must be a regular file
- app target is outside an allowed Applications directory
- artifact target has changed
- binary target is not an owned Caskroom symlink
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/74200156535613ae.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/packages/brew/pour.rs:52
/// without it is a remnant of a failed install and must not block a retry.
pub(super) fn keg_installed(name: &str, pkg_version: &str) -> bool {
keg_path(name, pkg_version).exists() && linked_version(name).as_deref() == Some(pkg_version)
}
/// the version `opt/<name>` points at, if the symlink resolves to an
/// existing keg
pub(super) fn linked_version(name: &str) -> Option<String> {
let opt = prefix::prefix().join("opt").join(name);
record_keg(name, &opt).map(|(version, _)| version)
}
/// Return the absolute opt path only when its symlink resolves to a keg directly inside the formula rack.
/// Preserve the configured prefix spelling and report invalid records without repairing them.
pub(super) fn strict_package_root(name: &str) -> Result<PathBuf> {
if let Some(prefix) = std::env::var_os("MISE_SYSTEM_BREW_PREFIX")
&& prefix.to_str().is_none()
{
bail!("the prefix cannot be printed as a single UTF-8 path; use a compatible prefix path");
}
let prefix = prefix::prefix();
let prefix = if prefix.is_absolute() {
prefix
} else {
std::env::current_dir()
.wrap_err_with(|| {
format!(
"cannot resolve relative Homebrew prefix {}",
prefix.display()
)
})?
.join(prefix)
};
let opt = prefix.join("opt").join(name);
let rack = prefix.join("Cellar").join(name);
let metadata =
std::fs::symlink_metadata(&opt).map_err(|err| package_root_io_error(name, &opt, err))?;View on GitHub (pinned to 533346cc37)