JanDeDobbeleer/oh-my-posh · error
unable to create fonts directory: %s
Error message
unable to create fonts directory: %s
What it means
On Windows, the font installer copies the font into the system/user fonts directory (`%LOCALAPPDATA%\Microsoft\Windows\Fonts` or `C:\Windows\Fonts`). This error wraps the failure of `os.MkdirAll(fontsDir, 0755)` when the directory doesn't exist and cannot be created — usually a permissions problem, not a missing parent.
Source
Thrown at src/cli/font/install_windows.go:34
const (
WM_FONTCHANGE = 0x001D
HWND_BROADCAST = 0xFFFF
)
func install(font *Font) error {
// To install a font on Windows:
// - Copy the file to the fonts directory
// - Add registry entry
// - Call AddFontResourceW to set the font
fontsDir := filepath.Join(os.Getenv("USERPROFILE"), "AppData", "Local", "Microsoft", "Windows", "Fonts")
log.Debugf("installing font %s to %s", font.FileName, fontsDir)
// check if the Fonts folder exists, if not, create it
if _, err := os.Stat(fontsDir); os.IsNotExist(err) {
if err = os.MkdirAll(fontsDir, 0755); err != nil {
return fmt.Errorf("unable to create fonts directory: %s", err.Error())
}
}
log.Debug("fonts directory exists, proceeding with installation")
fullPath := filepath.Join(fontsDir, font.FileName)
// validate if the font is already installed, remove it in case it is
if _, err := os.Stat(fullPath); err == nil {
log.Debugf("font %s already exists, removing it", fullPath)
if err = os.Remove(fullPath); err != nil {
return fmt.Errorf("unable to remove existing font file: %s", err.Error())
}
}
log.Debugf("writing font file to %s", fullPath)
err := os.WriteFile(fullPath, font.Data, 0644)
if err != nil {View on GitHub (pinned to 0976794618)
Solutions
- Run the terminal as Administrator if you intend a machine-wide install to C:\Windows\Fonts
- Prefer the per-user font install (no elevation needed) — ensure LOCALAPPDATA resolves correctly (`echo %LOCALAPPDATA%`)
- Check disk space and antivirus/EDR policies that block folder creation in Fonts
- Create the fonts directory manually once with proper ACLs, then retry
- Fix the user profile path if LOCALAPPDATA points to a nonexistent location
Example fix
// before: non-elevated attempt on machine fonts PS> oh-my-posh font install FiraCode # unable to create fonts directory // after: elevated PowerShell PS (admin)> oh-my-posh font install FiraCode
Defensive patterns
Strategy: validation
Validate before calling
# PowerShell pre-check before running the installer
$fontsDir = "$env:LOCALAPPDATA\Microsoft\Windows\Fonts"
if (-not (Test-Path $fontsDir)) {
try { New-Item -ItemType Directory -Path $fontsDir -ErrorAction Stop | Out-Null }
catch { Write-Error "Cannot create fonts dir: $_"; exit 1 }
} Prevention
- Use per-user font installs (default) to avoid needing elevation for C:\Windows\Fonts
- Ensure LOCALAPPDATA points to an existing, writable profile path
- Check AV/EDR policies that block directory creation before automating installs
When it happens
Trigger: `install` on Windows: `os.Stat(fontsDir)` reports IsNotExist, then `os.MkdirAll` fails (access denied writing to C:\Windows\Fonts without elevation, or the user profile path is unavailable/redirected).
Common situations: Running `oh-my-posh font install` in a non-elevated shell trying to write to C:\Windows\Fonts; roaming-profile or OneDrive-redirected LOCALAPPDATA; antivirus blocking directory creation; running under a service account with no profile.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- unable to delete font file after registry key open error
- unable to write font file: %s
- unable to open HKEY_CURRENT_USER
- unable to delete font file after registry key set error
- we do not have permissions to update
AI-assisted analysis of JanDeDobbeleer/oh-my-posh@0976794618 (2026-08-31).
Data as JSON: /api/errors/3947f924ec3d1a30.
Report an issue: GitHub.