{"record":{"id":"a9e5e96821ae0d10","repo":"spicetify/cli","slug":"error-decoding-utf-16le-content-w","errorCode":null,"errorMessage":"error decoding UTF-16LE content: %w","messagePattern":"error decoding UTF-16LE content: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/utils/file-utils.go","lineNumber":53,"sourceCode":"\tsearchStartMarker = encodeUTF16LE(startMarker)\n\tsearchEndMarker = encodeUTF16LE(endMarker)\n\n\tstartIdx = bytes.Index(contentToSearch, searchStartMarker)\n\tif startIdx == -1 {\n\t\treturn \"\", -1, -1, fmt.Errorf(\"start marker not found: %s\", string(startMarker))\n\t}\n\n\tsearchSpace := contentToSearch[startIdx+len(searchStartMarker):]\n\tendIdx = bytes.Index(searchSpace, searchEndMarker)\n\tif endIdx == -1 {\n\t\treturn \"\", -1, -1, fmt.Errorf(\"end marker not found after start index %d: %s\", startIdx+len(searchStartMarker), string(endMarker))\n\t}\n\n\tstringContentBytes := contentToSearch[startIdx : startIdx+len(searchStartMarker)+endIdx+len(searchEndMarker)]\n\n\tdecodedStringBytes, err := decodeUTF16LE(stringContentBytes)\n\tif err != nil {\n\t\treturn \"\", -1, -1, fmt.Errorf(\"error decoding UTF-16LE content: %w\", err)\n\t}\n\n\t// Adjust indices to be byte offsets in the original file\n\toriginalStartIdx := 2 + startIdx\n\toriginalEndIdx := 2 + endIdx + len(stringContentBytes)\n\treturn string(decodedStringBytes), originalStartIdx, originalEndIdx, nil\n}\n\n// Helper function to encode a byte slice (assumed UTF-8) to UTF-16LE\nfunc encodeUTF16LE(data []byte) []byte {\n\tutf16Bytes := utf16.Encode([]rune(string(data)))\n\tbyteSlice := make([]byte, len(utf16Bytes)*2)\n\tfor i, r := range utf16Bytes {\n\t\tbinary.LittleEndian.PutUint16(byteSlice[i*2:], r)\n\t}\n\n\treturn byteSlice\n}","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/spicetify/cli/blob/1f13f736163165234eef4fb792a03f9b5b732aa4/src/utils/file-utils.go#L35-L71","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: blind parse of a suspicious file\nval, _, _, err := utils.ReadStringFromUTF16Binary(prefs, start, end)\n// after: sanity-check file size is even after the 2-byte BOM first\nif fi, _ := os.Stat(prefs); fi != nil && fi.Size()%2 != 0 {\n\tlog.Fatal(\"prefs file has odd size; not valid UTF-16LE\")\n}\nval, _, _, err := utils.ReadStringFromUTF16Binary(prefs, start, end)","handlingStrategy":"validation","validationCode":"// Validate the region is decodable UTF-16 (even byte length) before/after extraction\nfunc validUTF16Region(data []byte) bool { return len(data)%2 == 0 }","typeGuard":"// Go: narrow via error unwrap\nfunc isDecodeErr(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"error decoding UTF-16LE content\")\n}","tryCatchPattern":"val, _, _, err := utils.ReadStringFromUTF16Binary(prefs, start, end)\nif err != nil {\n\tvar base error = err\n\tif errors.Unwrap(err) != nil { base = errors.Unwrap(err) }\n\treturn fmt.Errorf(\"utf16 decode failed (%v); file may be corrupt\", base)\n}","preventionTips":["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."],"tags":["go","utf16","encoding","decoding"],"backgroundTag":"utf16-decoding-failed","analyzedSha":"1f13f736163165234eef4fb792a03f9b5b732aa4","analyzedAt":"2026-08-31T18:57:59.754Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}