{"record":{"id":"1f3c96d906c57d23","repo":"jackwener/OpenCLI","slug":"minimax-music-audio-size-mismatch-expected-expe","errorCode":null,"errorMessage":"MiniMax music audio size mismatch (expected ${expectedBytes} bytes, got ${bytes.length})","messagePattern":"MiniMax music audio size mismatch \\(expected (.+?) bytes, got (.+?)\\)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/minimax/utils.js","lineNumber":154,"sourceCode":"    let url;\n    try {\n        url = new URL(value);\n    } catch {\n        throw new CommandExecutionError('MiniMax music returned data.audio that is not a URL');\n    }\n    if (url.protocol !== 'https:') {\n        throw new CommandExecutionError(`MiniMax music returned a non-HTTPS audio URL (${url.protocol})`);\n    }\n    return url.toString();\n}\n\nexport function decodeAudioHex(value, expectedBytes, format) {\n    if (value.length === 0 || value.length % 2 !== 0 || !/^[0-9a-f]+$/i.test(value)) {\n        throw new CommandExecutionError('MiniMax music returned invalid hexadecimal audio');\n    }\n    const bytes = Buffer.from(value, 'hex');\n    if (expectedBytes != null && bytes.length !== expectedBytes) {\n        throw new CommandExecutionError(`MiniMax music audio size mismatch (expected ${expectedBytes} bytes, got ${bytes.length})`);\n    }\n    if (format === 'wav' && (bytes.length < 12 || bytes.subarray(0, 4).toString('ascii') !== 'RIFF' || bytes.subarray(8, 12).toString('ascii') !== 'WAVE')) {\n        throw new CommandExecutionError('MiniMax music returned bytes that are not a WAV file');\n    }\n    if (format === 'mp3' && !isMp3(bytes)) {\n        throw new CommandExecutionError('MiniMax music returned bytes that are not an MP3 file');\n    }\n    return bytes;\n}\n\nfunction isMp3(bytes) {\n    return bytes.length >= 3 && bytes.subarray(0, 3).toString('ascii') === 'ID3'\n        || bytes.length >= 2 && bytes[0] === 0xff && (bytes[1] & 0xe0) === 0xe0;\n}\n\nexport function resolveOutputDir(value) {\n    const raw = String(value ?? '').trim();\n    if (!raw) return path.join(os.homedir(), 'Music', 'minimax');","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/minimax/utils.js#L136-L172","documentation":"After hex decoding, if the response supplied a trusted expected byte count (extra_info.music_size), the decoded buffer length must match exactly. A mismatch means the audio payload was truncated, padded, or corrupted in transit, so the client refuses to write a defective file.","triggerScenarios":"Network/proxy truncation of the response body; text-encoding mangling (e.g. the hex string passing through a UTF-16 or newline-joined transformation); mismatched music_size metadata from a buggy MiniMax job; double-decoding (decoding an already-decoded buffer re-encoded as hex).","commonSituations":"Corporate proxies or CDNs cutting off very large responses; shell pipelines stripping trailing characters from the hex string; custom HTTP clients with small default body buffers.","solutions":["Compare got vs expected in the message — a difference of a few bytes suggests truncation; re-run the request","Increase your HTTP client's max response body size / disable streaming limits","Fetch the audio over a direct connection to rule out proxy interference","Log payload.extra_info.music_size against the decoded length; if MiniMax consistently reports wrong sizes, report it and verify the audio manually (e.g. play the WAV)"],"exampleFix":"// before: single attempt, hard failure\nconst bytes = decodeAudioHex(data.audio, expectedBytes, 'wav');\n// after: re-fetch on mismatch\nlet bytes;\ntry {\n  bytes = decodeAudioHex(data.audio, expectedBytes, 'wav');\n} catch (e) {\n  if (!/size mismatch/.test(e.message)) throw e;\n  const retry = await fetchMusicAgain();\n  bytes = decodeAudioHex(retry.data.audio, retry.extra_info?.music_size ?? null, 'wav');\n}","handlingStrategy":"retry","validationCode":"// After decoding, verify before writing:\nconst bytes = Buffer.from(data.audio, 'hex');\nif (expectedBytes != null && bytes.length !== expectedBytes) {\n  console.warn(`size mismatch: expected ${expectedBytes}, got ${bytes.length} — refetch`);\n}","typeGuard":"function decodedSizeMatches(hex, expectedBytes) {\n  const bytes = Buffer.from(hex, 'hex');\n  return expectedBytes == null || bytes.length === expectedBytes;\n}","tryCatchPattern":"try {\n  const bytes = decodeAudioHex(value, expectedBytes, format);\n} catch (e) {\n  if (/size mismatch/.test(e.message)) {\n    // retry the fetch once over a direct connection before giving up\n  } else throw e;\n}","preventionTips":["Bypass proxies/CDNs when downloading large audio payloads","Set generous HTTP body-size limits in your client","Retry once on mismatch — truncation is often transient","Persist the raw hex payload on failure so it can be inspected/replayed","Log expected vs got sizes to distinguish truncation from metadata bugs"],"tags":["minimax","music","corruption","size-mismatch","network"],"backgroundTag":"payload-size-mismatch","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}