{"record":{"id":"efc1b6c2d65b170a","repo":"spicetify/cli","slug":"end-marker-not-found-after-start-index-d-s","errorCode":null,"errorMessage":"end marker not found after start index %d: %s","messagePattern":"end marker not found after start index (.+?): (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/utils/file-utils.go","lineNumber":46,"sourceCode":"\tvar searchStartMarker, searchEndMarker []byte\n\n\tif !isUTF16LE {\n\t\treturn \"\", -1, -1, fmt.Errorf(\"file is not in UTF-16LE format: %s\", inputFile)\n\t}\n\n\tcontentToSearch = fileContent[2:]\n\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)))","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/spicetify/cli/blob/1f13f736163165234eef4fb792a03f9b5b732aa4/src/utils/file-utils.go#L28-L64","documentation":"ReadStringFromUTF16Binary locates a delimited string inside a UTF-16LE file (e.g. Spotify prefs) by searching for an encoded start marker, then an encoded end marker after it. This error is returned when the start marker was found but bytes.Index never matches the UTF-16LE-encoded end marker in the remaining content. It wraps the end marker text in the message so the caller can see which delimiter was missing.","triggerScenarios":"Calling ReadStringFromUTF16Binary(inputFile, startMarker, endMarker) where the file contains the startMarker (UTF-16LE encoded) but no endMarker after it — e.g. a typo'd end marker, a marker in a different case/format than the file's encoding, or a truncated/corrupt file that lost the closing section.","commonSituations":"Parsing an older or newer version of the file whose delimiter strings changed; passing an ASCII end marker while the file stores UTF-16 (handled internally, but a wrong literal still fails); the file was cut off mid-write so the closing tag is absent; marker text differs by whitespace or capitalization from what the app wrote.","solutions":["Verify the end marker string matches exactly what the producing application writes (including case and spacing) and re-run.","Open the file in a UTF-16LE-aware hex/text editor and confirm the closing marker bytes actually exist after the start marker.","Check the reported start index in the error message and inspect bytes from there onward to see what text actually follows.","Regenerate or re-export the file if it is truncated/corrupt, then retry the parse."],"exampleFix":"// before: marker literal guess\ns, a, b, err := utils.ReadStringFromUTF16Binary(prefs, []byte(\"<name>\"), []byte(\"</Value>\"))\n// after: marker verified against the actual file content\ns, a, b, err := utils.ReadStringFromUTF16Binary(prefs, []byte(\"<name>\"), []byte(\"</name>\"))\nif err != nil {\n\tlog.Fatalf(\"parse prefs: %v\", err)\n}","handlingStrategy":"try-catch","validationCode":"// Go: check the file exists and is plausibly UTF-16LE before calling\nif fi, err := os.Stat(inputFile); err != nil || fi.Size() < 4 {\n\treturn fmt.Errorf(\"prefs file missing or too small\")\n}","typeGuard":"// Go has no runtime type guards; use an explicit error sentinel check\nfunc isEndMarkerNotFound(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"end marker not found\")\n}","tryCatchPattern":"val, _, _, err := utils.ReadStringFromUTF16Binary(prefs, start, end)\nif err != nil {\n\tif strings.Contains(err.Error(), \"end marker not found\") {\n\t\t// fall back to defaults or re-export the file\n\t\treturn defaultVal, nil\n\t}\n\treturn fmt.Errorf(\"parse prefs: %w\", err)\n}","preventionTips":["Copy marker strings directly from the real file's bytes instead of retyping them.","Log the reported start index and hex-dump the following bytes when debugging marker mismatches.","Handle file truncation: verify file size/parity before parsing UTF-16 content.","Wrap this parser in a helper that maps marker errors to a clear domain error."],"tags":["go","utf16","parser","marker-not-found"],"backgroundTag":"end-marker-not-found","analyzedSha":"1f13f736163165234eef4fb792a03f9b5b732aa4","analyzedAt":"2026-08-31T18:57:59.754Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}