{"record":{"id":"e18b3d3f15df3170","repo":"jackwener/OpenCLI","slug":"minimax-music-returned-malformed-extra-info","errorCode":null,"errorMessage":"MiniMax music returned malformed extra_info","messagePattern":"MiniMax music returned malformed extra_info","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/minimax/utils.js","lineNumber":126,"sourceCode":"            `MiniMax music returned status 1 (in progress) without a resumable task id${traceId ? ` (trace_id: ${traceId})` : ''}`,\n            'Do not resubmit blindly: this endpoint exposes no query command, so check MiniMax account history first.',\n        );\n    }\n    if (data.status !== 2) {\n        throw new CommandExecutionError(`MiniMax music returned unknown data.status ${data.status}`);\n    }\n    if (typeof data.audio !== 'string' || !data.audio.trim()) {\n        throw new CommandExecutionError('MiniMax music reported completion without data.audio');\n    }\n    return {\n        audio: data.audio.trim(),\n        expectedBytes: payload.extra_info == null ? null : parseExpectedSize(payload.extra_info),\n    };\n}\n\nfunction parseExpectedSize(extraInfo) {\n    if (!extraInfo || typeof extraInfo !== 'object' || Array.isArray(extraInfo)) {\n        throw new CommandExecutionError('MiniMax music returned malformed extra_info');\n    }\n    if (extraInfo.music_size == null) return null;\n    if (!Number.isSafeInteger(extraInfo.music_size) || extraInfo.music_size <= 0) {\n        throw new CommandExecutionError('MiniMax music returned invalid extra_info.music_size');\n    }\n    return extraInfo.music_size;\n}\n\nexport function requireAudioUrl(value) {\n    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    }","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/minimax/utils.js#L108-L144","documentation":"parseExpectedSize validates payload.extra_info, which should carry the expected decoded audio byte count. If extra_info is present (non-null) but is not a plain object (null handled earlier, or a string/number/array), the client treats the response as malformed and throws, since it cannot trust the size metadata.","triggerScenarios":"MiniMax returns extra_info as a JSON string instead of an object, as an array, or the client wraps it differently; API schema change altering extra_info's type.","commonSituations":"Proxy or middleware re-serializing the response body; older/newer MiniMax API versions with different extra_info encoding; hand-rolled test fixtures passing the wrong shape.","solutions":["Log payload.extra_info and its typeof to see what was actually returned","If extra_info arrives as a JSON string, JSON.parse it before calling the parse path","Pin/verify the MiniMax API version you are calling matches the client's expected schema","If you do not need byte verification, check whether the client supports omitting/ignoring extra_info (it returns null only when the field is absent)"],"exampleFix":"// before: passing raw body\nparseCompletedMusic(body);\n// after: normalize stringified extra_info\nif (typeof body.extra_info === 'string') {\n  try { body.extra_info = JSON.parse(body.extra_info); } catch { body.extra_info = null; }\n}\nparseCompletedMusic(body);","handlingStrategy":"type-guard","validationCode":"if (payload.extra_info != null &&\n    (typeof payload.extra_info !== 'object' || Array.isArray(payload.extra_info))) {\n  if (typeof payload.extra_info === 'string') {\n    payload.extra_info = JSON.parse(payload.extra_info);\n  }\n}","typeGuard":"function isPlainObject(v) {\n  return v != null && typeof v === 'object' && !Array.isArray(v);\n}","tryCatchPattern":"try {\n  const result = parseCompletedMusic(payload);\n} catch (e) {\n  if (/malformed extra_info/.test(e.message)) {\n    console.error('extra_info shape:', typeof payload.extra_info, JSON.stringify(payload.extra_info));\n  } else throw e;\n}","preventionTips":["Normalize stringified extra_info before parsing","Record real API responses as fixtures","Confirm middleware is not re-serializing response bodies","Pin the MiniMax API version"],"tags":["minimax","music","schema-validation","extra-info"],"backgroundTag":"schema-validation-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}