jdx/mise · error · eyre::Report

font target is outside the platform font directory: {}

Error message

font target is outside the platform font directory: {}

What it means

Font targets must be regular files beneath the platform font directory (font_dir(), e.g. ~/Library/Fonts on macOS) whose staged counterpart at version_dir/<relative-path> fingerprints identically. Fonts outside that directory, wrong file types, or mismatched staged copies block pruning of the cask.

Source

Thrown at src/system/packages/brew/cask.rs:7083

        {
            bail!(
                "binary target is not an owned Caskroom symlink: {}",
                path.display()
            );
        }
    }
    for path in &receipt.fonts {
        let record = records
            .get(path)
            .ok_or_else(|| eyre!("missing font target record"))?;
        let fonts = font_dir();
        if record.fingerprint.kind != CaskTargetKind::File
            || !path_is_below(path, &fonts)
            || !path.strip_prefix(&fonts).is_ok_and(|relative| {
                staged_target_matches(record, &candidate.version_dir.join(relative))
            })
        {
            bail!(
                "font target is outside the platform font directory: {}",
                path.display()
            );
        }
    }
    let completion_roots = [
        CompletionShell::Bash,
        CompletionShell::Fish,
        CompletionShell::Zsh,
        CompletionShell::Pwsh,
    ]
    .map(default_completion_dir);
    for path in &receipt.completions {
        let record = records
            .get(path)
            .ok_or_else(|| eyre!("missing completion target record"))?;
        if record.fingerprint.kind != CaskTargetKind::Symlink
            || !completion_roots

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Move the font file back under the platform font directory at its original relative path
  2. Restore or reinstall the cask so Caskroom/<token>/<version>/<font-path> exists and hashes identically
  3. If the font was intentionally relocated, remove it manually and uninstall the cask rather than pruning
Defensive patterns

Strategy: validation

Validate before calling

// Confirm font targets remain regular files under the platform font dir
// with an intact staged copy before pruning.
fn font_ok(record_path: &Path, version_dir: &Path, fingerprint: &CaskTargetFingerprint) -> bool {
    let fonts = font_dir();
    path_is_below(record_path, &fonts)
        && record_path.strip_prefix(&fonts).is_ok_and(|rel| {
            staged_target_matches_fingerprint(&version_dir.join(rel), fingerprint)
        })
}

Type guard

fn font_in_font_dir(path: &Path) -> bool {
    path_is_below(path, &font_dir())
        && path.symlink_metadata().map(|m| m.is_file()).unwrap_or(false)
}

Try / catch

// Same skip-not-abort pattern: one bad font skips only its cask.
if let Err(reason) = validate_cask_prune_candidate(candidate) {
    plan.skipped.push(CaskPruneSkip { token: candidate.token, reason: format!("{reason:#}") });
    continue;
}

Prevention

When it happens

Trigger: validate_cask_prune_candidate, fonts loop: fingerprint kind != File, path not below font_dir(), or staged_target_matches fails for version_dir.join(relative). Caused by moving/renaming installed fonts, deleting the staged copy in Caskroom, or font-manager tools rewriting files (hash changes surface as mismatch).

Common situations: User reorganized fonts into /Library/Fonts or a font-manager vault; staged Caskroom copy purged; font activated/copied by tools like Font Book altering the original.

Related errors


AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17). Data as JSON: /api/errors/2d38e73146e93236. Report an issue: GitHub.