spicetify/cli · error
error decoding UTF-16LE content: %w
Error message
error decoding UTF-16LE content: %w
What it means
After slicing out the marker-delimited region, ReadStringFromUTF16Binary passes those bytes to decodeUTF16LE to convert UTF-16LE to UTF-8. If decoding fails, the error is wrapped as "error decoding UTF-16LE content: %w". Currently the only underlying failure decodeUTF16LE produces is an odd-length byte slice, so this error almost always means the extracted region has an odd number of bytes.
Source
Thrown at src/utils/file-utils.go:53
searchStartMarker = encodeUTF16LE(startMarker)
searchEndMarker = encodeUTF16LE(endMarker)
startIdx = bytes.Index(contentToSearch, searchStartMarker)
if startIdx == -1 {
return "", -1, -1, fmt.Errorf("start marker not found: %s", string(startMarker))
}
searchSpace := contentToSearch[startIdx+len(searchStartMarker):]
endIdx = bytes.Index(searchSpace, searchEndMarker)
if endIdx == -1 {
return "", -1, -1, fmt.Errorf("end marker not found after start index %d: %s", startIdx+len(searchStartMarker), string(endMarker))
}
stringContentBytes := contentToSearch[startIdx : startIdx+len(searchStartMarker)+endIdx+len(searchEndMarker)]
decodedStringBytes, err := decodeUTF16LE(stringContentBytes)
if err != nil {
return "", -1, -1, fmt.Errorf("error decoding UTF-16LE content: %w", err)
}
// Adjust indices to be byte offsets in the original file
originalStartIdx := 2 + startIdx
originalEndIdx := 2 + endIdx + len(stringContentBytes)
return string(decodedStringBytes), originalStartIdx, originalEndIdx, nil
}
// Helper function to encode a byte slice (assumed UTF-8) to UTF-16LE
func encodeUTF16LE(data []byte) []byte {
utf16Bytes := utf16.Encode([]rune(string(data)))
byteSlice := make([]byte, len(utf16Bytes)*2)
for i, r := range utf16Bytes {
binary.LittleEndian.PutUint16(byteSlice[i*2:], r)
}
return byteSlice
}View on GitHub (pinned to 1f13f73616)
Solutions
- Inspect the bytes between the markers to confirm the region is a whole number of UTF-16 code units (even byte count).
- Check that start/end markers are distinct and non-overlapping so the slice boundary math is correct.
- Re-obtain the file from the application rather than using a hand-edited or partially converted copy.
- Unwrap the %w error to confirm it is the odd-length case, then validate the file's UTF-16LE integrity before parsing.
Example fix
// before: blind parse of a suspicious file
val, _, _, err := utils.ReadStringFromUTF16Binary(prefs, start, end)
// after: sanity-check file size is even after the 2-byte BOM first
if fi, _ := os.Stat(prefs); fi != nil && fi.Size()%2 != 0 {
log.Fatal("prefs file has odd size; not valid UTF-16LE")
}
val, _, _, err := utils.ReadStringFromUTF16Binary(prefs, start, end) Defensive patterns
Strategy: validation
Validate before calling
// Validate the region is decodable UTF-16 (even byte length) before/after extraction
func validUTF16Region(data []byte) bool { return len(data)%2 == 0 } Type guard
// Go: narrow via error unwrap
func isDecodeErr(err error) bool {
return err != nil && strings.Contains(err.Error(), "error decoding UTF-16LE content")
} Try / catch
val, _, _, err := utils.ReadStringFromUTF16Binary(prefs, start, end)
if err != nil {
var base error = err
if errors.Unwrap(err) != nil { base = errors.Unwrap(err) }
return fmt.Errorf("utf16 decode failed (%v); file may be corrupt", base)
} Prevention
- Never hand-edit UTF-16LE files with ASCII editors; use an encoding-aware editor.
- Verify start/end markers are unique and non-overlapping in the target file.
- Check overall file size is even after the BOM before parsing.
- Re-fetch or re-export suspect files rather than patching bytes in place.
When it happens
Trigger: Calling ReadStringFromUTF16Binary when the bytes between (and including) the start and end markers have odd length. Note the slicing arithmetic at file-utils.go:49 uses endIdx relative to the search space combined with marker lengths, so overlapping/duplicated markers or a malformed region can produce an odd-length slice that fails UTF-16 decoding.
Common situations: A file edited by hand where the delimiters no longer pair up cleanly; start and end markers that overlap or occur an odd number of bytes apart; a file that was partially converted between encodings so the region contains stray single bytes; using markers that themselves contain multi-byte surrogate characters and mismatched pairs.
Related errors
- invalid UTF-16LE data length
- file is not in UTF-16LE format: %s
- end marker not found after start index %d: %s
- error reading file %s: %w
- start marker not found: %s
AI-assisted analysis of spicetify/cli@1f13f73616 (2026-08-31).
Data as JSON: /api/errors/a9e5e96821ae0d10.
Report an issue: GitHub.