jdx/mise · error
brew-cask: invalid font target '{}'
Error message
brew-cask: invalid font target '{}' What it means
The final font install path is font_dir().join(name), where the name is derived from the cask's font stanza. font_target_path requires that name to be a non-empty, purely relative filename: not absolute and free of '..' components, so a font can never be written outside the user's font directory.
Source
Thrown at src/system/packages/brew/cask.rs:2778
.filter(|entry| entry.file_type().is_ok_and(|ft| ft.is_dir()))
.any(|entry| relative.is_some_and(|path| entry.path().join(path).is_file()));
if has_staged_copy {
file::remove_file(target)?;
}
}
Ok(())
}
fn font_target_path(font: &FontArtifact) -> Result<PathBuf> {
let name = font_filename(font)?;
let name_path = Path::new(&name);
if name_path.is_absolute()
|| name_path
.components()
.any(|component| matches!(component, Component::ParentDir))
|| name_path.components().next().is_none()
{
bail!("brew-cask: invalid font target '{}'", name);
}
Ok(font_dir().join(name_path))
}
fn font_dir() -> PathBuf {
if cfg!(target_os = "linux") {
crate::env::XDG_DATA_HOME.join("fonts")
} else {
crate::dirs::HOME.join("Library").join("Fonts")
}
}
#[cfg(test)]
fn execute_flight_steps(
cask: &Cask,
steps: &[FlightStep],
staged_path: &Path,
appdir: &Path,View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Fix the font stanza to a plain file name like "MyFont-Regular.otf"
- Strip directory components from the name before it reaches font handling
- Report malformed stanzas in third-party taps upstream
Example fix
# before font: "/Library/Fonts/MyFont.ttf" # after font: "MyFont.ttf"
Defensive patterns
Strategy: validation
Validate before calling
use std::path::{Path, Component};
fn is_plain_filename(name: &str) -> bool {
let p = Path::new(name);
!p.is_absolute()
&& p.components().next().is_some()
&& !p.components().any(|c| matches!(c, Component::ParentDir))
} Type guard
fn is_plain_font_filename(name: &str) -> bool {
let p = std::path::Path::new(name);
!p.is_absolute() && p.components().next().is_some()
&& !p.components().any(|c| matches!(c, std::path::Component::ParentDir))
} Prevention
- Write font stanzas as bare filenames, never paths
- Resolve template variables before passing font names
- Reject absolute or dot-dot font names in cask linting
When it happens
Trigger: A font filename that starts with '/' or contains '..' after expansion from the cask stanza; an empty or placeholder filename that resolves to zero components.
Common situations: Hand-written casks with absolute font paths; unresolved template variables leaving '.'/'..' fragments; malformed font stanzas in third-party taps.
Related errors
- mise upgrade --monorepo is not implemented yet
- brew-cask: refusing generic artifact copy outside Homebrew p
- brew-cask: invalid generic artifact parent
- brew-cask: refusing installer executable outside trusted ins
- brew-cask: generic artifact target '{}' must stay below {}
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/3a7706c610ed3763.
Report an issue: GitHub.