{"record":{"id":"a106cdf79662a7c0","repo":"mudler/LocalAI","slug":"bytestoint16sle-input-bytes-slice-has-odd-length","errorCode":null,"errorMessage":"bytesToInt16sLE: input bytes slice has odd length, must be even","messagePattern":"bytesToInt16sLE: input bytes slice has odd length, must be even","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/sound/int16.go","lineNumber":82,"sourceCode":"\t\t// Linearly interpolate between the two surrounding input samples\n\t\toutput[i] = int16((1-frac)*float64(input[indexBefore]) + frac*float64(input[indexAfter]))\n\t}\n\n\treturn output\n}\n\nfunc ConvertInt16ToInt(input []int16) []int {\n\toutput := make([]int, len(input)) // Allocate a slice for the output\n\tfor i, value := range input {\n\t\toutput[i] = int(value) // Convert each int16 to int and assign it to the output slice\n\t}\n\treturn output // Return the converted slice\n}\n\nfunc BytesToInt16sLE(bytes []byte) []int16 {\n\t// Ensure the byte slice length is even\n\tif len(bytes)%2 != 0 {\n\t\tpanic(\"bytesToInt16sLE: input bytes slice has odd length, must be even\")\n\t}\n\n\tint16s := make([]int16, len(bytes)/2)\n\tfor i := range len(int16s) {\n\t\tint16s[i] = int16(bytes[2*i]) | int16(bytes[2*i+1])<<8\n\t}\n\treturn int16s\n}\n\nfunc Int16toBytesLE(arr []int16) []byte {\n\tle := binary.LittleEndian\n\tresult := make([]byte, 0, 2*len(arr))\n\tfor _, val := range arr {\n\t\tresult = le.AppendUint16(result, uint16(val))\n\t}\n\treturn result\n}\n","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/mudler/LocalAI/blob/44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26/pkg/sound/int16.go#L64-L100","documentation":"Panic in pkg/sound BytesToInt16sLE when the input byte slice has an odd number of bytes. The function reinterprets bytes as little-endian int16 pairs (two bytes per sample), so an odd length means half a sample — usually a truncated audio buffer — and rather than silently drop a byte it panics.","triggerScenarios":"Feeding PCM16 audio whose length is not a multiple of 2: a chunked stream split mid-sample, a buffer sliced with an off-by-one, or raw bytes from a source that includes a header/odd-sized footer concatenated with samples.","commonSituations":"Streaming TTS/ASR pipelines that chunk audio at arbitrary byte boundaries; mixing mono/stereo or headered formats (WAV headers stripped incorrectly); len(buf)-1 style slicing bugs; network reads returning partial frames.","solutions":["Trim to even length before calling: process buf[:len(buf)-len(buf)%2] and carry the leftover byte into the next chunk","For streams, buffer bytes and only convert when >=2 bytes are available, keeping the remainder","Check upstream for truncation: verify the producer is sending whole PCM16 frames","Use Int16toBytesLE / matching helpers on the producer side so lengths stay multiples of two"],"exampleFix":"// before\nsamples := sound.BytesToInt16sLE(chunk) // panics on odd chunk\n// after\nif odd := len(chunk) % 2; odd != 0 {\n    chunk = chunk[:len(chunk)-1] // or stash last byte for next chunk\n}\nsamples := sound.BytesToInt16sLE(chunk)","handlingStrategy":"validation","validationCode":"func toInt16Safe(b []byte) ([]int16, []byte) {\n    n := len(b) - len(b)%2\n    return sound.BytesToInt16sLE(b[:n]), b[n:]\n}","typeGuard":"func isEvenLength(b []byte) bool { return len(b)%2 == 0 }","tryCatchPattern":"// panics in Go; if the boundary is untrusted, wrap it\nfunc safeBytesToInt16sLE(b []byte) (out []int16, err error) {\n    defer func() { if r := recover(); r != nil { err = fmt.Errorf(\"odd byte length: %d\", len(b)) } }()\n    return sound.BytesToInt16sLE(b), nil\n}","preventionTips":["Always frame PCM16 streams in whole-sample (2-byte) chunks","Carry leftover odd bytes into the next chunk in streaming loops","Log byte counts at chunk boundaries to catch truncation early"],"tags":["audio","pcm","validation","panic","go"],"backgroundTag":null,"analyzedSha":"44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26","analyzedAt":"2026-08-15T10:13:50.291Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}