JanDeDobbeleer/oh-my-posh · critical

unable to delete font file after registry key set error

Error message

unable to delete font file after registry key set error

What it means

After opening the fonts registry key, install writes the font's name/value pair with SetStringValue. If that write fails, it tries to delete the extracted font file as rollback; when the delete also fails it returns this error. Both the registry value write and the file cleanup failed, leaving the font file on disk but unregistered.

Source

Thrown at src/cli/font/install_windows.go:128

	gdi32 := syscall.NewLazyDLL("gdi32.dll")
	addFontResourceW := gdi32.NewProc("AddFontResourceW")

	// remove the old font resource in case we have a new font type with the same name
	if newFontType {
		log.Debug("removing old font resource before adding new one")
		fontPtr, err := syscall.UTF16PtrFromString(oldFullPath)
		if err == nil {
			removeFontResourceW := gdi32.NewProc("RemoveFontResourceW")
			_, _, _ = removeFontResourceW.Call(uintptr(unsafe.Pointer(fontPtr)))
		}
	}

	if err = k.SetStringValue(fontName, regValue); err != nil {
		log.Error(err)
		// If this fails, remove the font file as well.
		if nexterr := os.Remove(fullPath); nexterr != nil {
			return errors.New("unable to delete font file after registry key set error")
		}

		return fmt.Errorf("unable to set registry value: %s", err.Error())
	}

	fontPtr, err := syscall.UTF16PtrFromString(fullPath)
	if err != nil {
		return err
	}

	ret, _, _ := addFontResourceW.Call(uintptr(unsafe.Pointer(fontPtr)))
	if ret == 0 {
		return errors.New("unable to add font resource using AddFontResourceW")
	}

	log.Debug("font resource added successfully")

	return nil

View on GitHub (pinned to 0976794618)

Solutions

  1. Close apps holding the font file open, delete the leftover font file manually, then retry the install.
  2. Check registry write permissions/quota for HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts.
  3. Retry after excluding the font directory from antivirus real-time scanning.
  4. Manually register the font (copy to %WINDIR%\Fonts or double-click install) as a fallback.
Defensive patterns

Strategy: try-catch

Validate before calling

// verify the key is writable and the target path is deletable before install
k, err := registry.OpenKey(registry.CURRENT_USER, `SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts`, registry.SET_VALUE)
if err != nil { return err }
k.Close()
if f, err := os.OpenFile(fullPath, os.O_WRONLY, 0); err != nil { return err } else { f.Close(); os.Remove(fullPath) }

Try / catch

if err := font.Install(env, name, report); err != nil {
    if strings.Contains(err.Error(), "after registry key set error") {
        log.Printf("registry write failed and font file is stranded; delete it manually and check registry quota/policy")
    }
    return err
}

Prevention

When it happens

Trigger: registry.CreateKey succeeded but k.SetStringValue(fontName, regValue) returns an error (key handle invalid, hive quota, ACL change) AND os.Remove(fullPath) fails because the file is locked or permission-denied.

Common situations: Registry quota exceeded for the user hive; security software blocking registry writes mid-operation; the font file locked by a preview window or antivirus while cleanup is attempted.

Related errors


AI-assisted analysis of JanDeDobbeleer/oh-my-posh@0976794618 (2026-08-31). Data as JSON: /api/errors/4ce1fe33cd11cd6c. Report an issue: GitHub.