jdx/mise · error

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

Error message

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

What it means

After staging a cask's payload, mise links declared font artifacts from the caskroom into the user's font directory. Before linking, it verifies the staged font file actually exists at the expected caskroom path; this error is thrown when the font artifact named in the cask definition was not found in the staged output.

Source

Thrown at src/system/packages/brew/cask/mod.rs:2485

    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 afd2eddd3a)

Solutions

  1. Re-run the cask install so staging completes fully before linking
  2. Check the cask definition's font source path against what was actually staged (list the caskroom contents)
  3. Update mise / the cask definition if the upstream font was renamed
  4. Report the cask as broken upstream if the artifact name no longer matches

Example fix

// before: stale staged font from failed install
rm -rf <caskroom-dir> && mise install <cask>
// after: fresh stage then link succeeds
Defensive patterns

Strategy: validation

Validate before calling

test -f <caskroom>/<cask>/<font-source> || echo "font artifact missing from stage"

Try / catch

match result {
  Err(e) if e.contains("font artifact") && e.contains("was not staged") => {
    eprintln!("staged font missing; reinstall cask to restage: {e}");
  }
  Err(e) => return Err(e),
  Ok(v) => v,
}

Prevention

When it happens

Trigger: `link_font` calls `caskroom_font_path(caskroom, font)` and `!caskroom_font.is_file()` — the cask declared a `font` stanza whose staged file is missing, was renamed upstream, or staging partially failed.

Common situations: A cask definition references a font file whose upstream URL/name changed; a partial or failed stage left the caskroom incomplete; the cask's artifact list drifted from what the installer actually downloaded.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/9095f10b4a24c037. Report an issue: GitHub.