{"record":{"id":"4ce1fe33cd11cd6c","repo":"JanDeDobbeleer/oh-my-posh","slug":"unable-to-delete-font-file-after-registry-key-set","errorCode":null,"errorMessage":"unable to delete font file after registry key set error","messagePattern":"unable to delete font file after registry key set error","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/cli/font/install_windows.go","lineNumber":128,"sourceCode":"\n\tgdi32 := syscall.NewLazyDLL(\"gdi32.dll\")\n\taddFontResourceW := gdi32.NewProc(\"AddFontResourceW\")\n\n\t// remove the old font resource in case we have a new font type with the same name\n\tif newFontType {\n\t\tlog.Debug(\"removing old font resource before adding new one\")\n\t\tfontPtr, err := syscall.UTF16PtrFromString(oldFullPath)\n\t\tif err == nil {\n\t\t\tremoveFontResourceW := gdi32.NewProc(\"RemoveFontResourceW\")\n\t\t\t_, _, _ = removeFontResourceW.Call(uintptr(unsafe.Pointer(fontPtr)))\n\t\t}\n\t}\n\n\tif err = k.SetStringValue(fontName, regValue); err != nil {\n\t\tlog.Error(err)\n\t\t// If this fails, remove the font file as well.\n\t\tif nexterr := os.Remove(fullPath); nexterr != nil {\n\t\t\treturn errors.New(\"unable to delete font file after registry key set error\")\n\t\t}\n\n\t\treturn fmt.Errorf(\"unable to set registry value: %s\", err.Error())\n\t}\n\n\tfontPtr, err := syscall.UTF16PtrFromString(fullPath)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tret, _, _ := addFontResourceW.Call(uintptr(unsafe.Pointer(fontPtr)))\n\tif ret == 0 {\n\t\treturn errors.New(\"unable to add font resource using AddFontResourceW\")\n\t}\n\n\tlog.Debug(\"font resource added successfully\")\n\n\treturn nil","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/JanDeDobbeleer/oh-my-posh/blob/0976794618c5ed95de0985dded50de1b4dc914cb/src/cli/font/install_windows.go#L110-L146","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Close apps holding the font file open, delete the leftover font file manually, then retry the install.","Check registry write permissions/quota for HKCU\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts.","Retry after excluding the font directory from antivirus real-time scanning.","Manually register the font (copy to %WINDIR%\\Fonts or double-click install) as a fallback."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// verify the key is writable and the target path is deletable before install\nk, err := registry.OpenKey(registry.CURRENT_USER, `SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts`, registry.SET_VALUE)\nif err != nil { return err }\nk.Close()\nif f, err := os.OpenFile(fullPath, os.O_WRONLY, 0); err != nil { return err } else { f.Close(); os.Remove(fullPath) }","typeGuard":null,"tryCatchPattern":"if err := font.Install(env, name, report); err != nil {\n    if strings.Contains(err.Error(), \"after registry key set error\") {\n        log.Printf(\"registry write failed and font file is stranded; delete it manually and check registry quota/policy\")\n    }\n    return err\n}","preventionTips":["Pre-check registry SET_VALUE access before automated font installs","Keep font files out of use (no preview windows) during install so rollback deletes can succeed","Watch user registry quota on machines with many per-user fonts"],"tags":["windows","registry","font","filesystem"],"backgroundTag":"registry-write-failed","analyzedSha":"0976794618c5ed95de0985dded50de1b4dc914cb","analyzedAt":"2026-08-31T23:41:19.708Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}