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

  1. Fix the cache directory path env var (TMP, TEMP, USERPROFILE, XDG_CACHE_HOME) to a valid location
  2. Inspect the printed path for a NUL byte or invalid characters and remove its source
  3. Point the cache to a plain ASCII path via the appropriate oh-my-posh cache env setting
  4. 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

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


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