jdx/mise · error

brew-cask: font artifact '{}' was not staged

Error message

brew-cask: font artifact '{}' was not staged

What it means

Font installation is two-phase: an earlier step copies the font file into the Caskroom, then link_font copies it into the user font directory. link_font requires the staged Caskroom file to exist as a regular file; if it does not, the staging phase did not produce the expected file at the expected name.

Source

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

    sudo::run("installer", &args, &[])
}

fn stage_font(stage: &Path, caskroom: &Path, font: &FontArtifact) -> Result<()> {
    let caskroom_font = caskroom_font_path(caskroom, font)?;
    file::remove_all(&caskroom_font)?;
    if let Some(parent) = caskroom_font.parent() {
        file::create_dir_all(parent)?;
    }
    let source = find_file_artifact(stage, &font.source)
        .ok_or_else(|| eyre!("brew-cask: font artifact '{}' was not found", font.source))?;
    copy_cask_artifact(&source, &caskroom_font)?;
    Ok(())
}

fn link_font(caskroom: &Path, font: &FontArtifact) -> Result<()> {
    let caskroom_font = caskroom_font_path(caskroom, font)?;
    if !caskroom_font.is_file() {
        bail!("brew-cask: font artifact '{}' was not staged", font.source);
    }
    let target = font_target_path(font)?;
    if let Some(parent) = target.parent() {
        file::create_dir_all(parent)?;
    }
    // Atomic swap: rename existing font aside before copying the new one so
    // that a failure during copy leaves the old font intact.
    let old_target = target.with_extension(format!(
        "mise-old-{}",
        crate::hash::hash_to_str(&target.display().to_string())
    ));
    file::remove_all(&old_target)?;
    if target.exists() {
        file::rename(&target, &old_target)?;
    }
    if let Err(e) = copy_cask_artifact(&caskroom_font, &target) {
        if old_target.exists() {
            let _ = file::rename(&old_target, &target);

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Inspect the caskroom font directory (see caskroom_font_path) and compare with the font stanza's source
  2. Fix font.source in the cask to the real file name/path
  3. Uninstall and reinstall the cask so staging reruns cleanly

Example fix

# before -- upstream renamed the file
font: "MyFont-Regular.otf"

# after
font: "MyFont-Regular.ttf"
Defensive patterns

Strategy: validation

Validate before calling

let staged = caskroom_font_path(caskroom, font)?;
if !staged.is_file() {
    anyhow::bail!(
        "font '{}' not staged into caskroom; run the copy step first (found: {:?})",
        font.source,
        staged.exists()
    );
}

Prevention

When it happens

Trigger: font.source in the cask not matching the file actually extracted (renamed upstream, case difference, nested path); the copy/staging step skipped or failed; caskroom path computed with a different filename between the two phases.

Common situations: Upstream releases renaming font files; stale or partial installs where the Caskroom copy is absent; casks whose font stanza references a nested or differently-cased path.

Related errors


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