JanDeDobbeleer/oh-my-posh · error
failed to convert file path to UTF16: %v
Error message
failed to convert file path to UTF16: %v
What it means
On Windows, the cache layer's createNewFileWithSize converts the file path to a UTF-16 pointer via syscall.UTF16PtrFromString before calling CreateFileW. If the path contains an unpaired surrogate or otherwise can't be represented as valid UTF-16, it fails with 'failed to convert file path to UTF16: %v'.
Source
Thrown at src/cache/file_map_windows.go:163
return nil, fmt.Errorf("failed to get file size")
}
actualSize := int(fileSize) - 5 // Subtract header (4 bytes length + 1 null terminator)
if actualSize < requiredSize {
// Existing file is too small, close and recreate
_, _, _ = closeHandle.Call(fileHandle)
return nil, fmt.Errorf("existing file is too small (%d < %d)", actualSize, requiredSize)
}
return createMappingFromFileWithSize(filePath, fileHandle, actualSize)
}
// Created with FILE_SHARE_READ|FILE_SHARE_WRITE so subsequent concurrent
// opens by other processes don't fail with a sharing violation.
func createNewFileWithSize(filePath string, size int) (*PersistentSharedString, error) {
filePathPtr, err := syscall.UTF16PtrFromString(filePath)
if err != nil {
return nil, fmt.Errorf("failed to convert file path to UTF16: %v", err)
}
// Create new file
fileHandle, _, err := createFileW.Call(
uintptr(unsafe.Pointer(filePathPtr)), // lpFileName
genericRead|genericWrite, // dwDesiredAccess
fileShareRead|fileShareWrite, // dwShareMode
0, // lpSecurityAttributes
createAlways, // dwCreationDisposition (overwrites if exists)
fileAttributeNormal, // dwFlagsAndAttributes
0, // hTemplateFile
)
if fileHandle == uintptr(0xFFFFFFFFFFFFFFFF) { // INVALID_HANDLE_VALUE
if errno, ok := err.(syscall.Errno); ok && uintptr(errno) == errorSharingViolation {
log.Debugf("cache file %s locked by another process during create", filePath)
return nil, ErrLocked
}View on GitHub (pinned to 0976794618)
Solutions
- Fix the cache directory path env var (TMP, TEMP, USERPROFILE, XDG_CACHE_HOME) to a valid location
- Inspect the printed path for a NUL byte or invalid characters and remove its source
- Point the cache to a plain ASCII path via the appropriate oh-my-posh cache env setting
- Clear any corrupted cache path configuration and recreate the cache directory
Example fix
// before: TMP set to a path with a NUL byte TMP=C:\Users\bad\x00cache // after TMP=C:\Users\me\AppData\Local\Temp
Defensive patterns
Strategy: validation
Validate before calling
// validate the path before handing it to the API (Go)
func validUTF16Path(p string) bool {
_, err := syscall.UTF16PtrFromString(p)
return err == nil
} Try / catch
// wrap creation and fall back to a sanitized path
ps, err := createNewFileWithSize(filePath, size)
if err != nil {
clean := filepath.Clean(strings.ReplaceAll(filePath, "\x00", ""))
ps, err = createNewFileWithSize(clean, size)
} Prevention
- Keep TMP/TEMP/USERPROFILE free of invalid characters
- Never concatenate user input with NUL bytes into file paths
- Sanitize cache paths with filepath.Clean and UTF-8 validation
- Point the cache at a stable ASCII directory on Windows
When it happens
Trigger: createOrOpenFile/createOrOpenPersistentStringWithSize is invoked with a cache file path containing invalid UTF-8 sequences or an embedded NUL character, making UTF16PtrFromString fail (ErrInvalidUtf8 or unexpected NUL).
Common situations: Cache directory (TMP/USERPROFILE/XDG_CACHE_HOME) containing non-representable characters from a corrupted env var; a username with invalid encoding; a path built by concatenating user input containing a NUL byte.
Related errors
- unable to delete font file after registry key open error
- unable to delete font file after registry key set error
- unable to create fonts directory: %s
- unable to remove existing font file: %s
- unable to write font file: %s
AI-assisted analysis of JanDeDobbeleer/oh-my-posh@0976794618 (2026-08-31).
Data as JSON: /api/errors/df4e45a9aa5f404c.
Report an issue: GitHub.