jackwener/OpenCLI · error · CommandExecutionError
MiniMax music returned data.audio that is not a URL
Error message
MiniMax music returned data.audio that is not a URL
What it means
requireAudioUrl runs data.audio through new URL() and throws when the value cannot be parsed as a URL at all — meaning the audio field held something else (raw hex, base64, a bare path, or empty string). This guards the URL-based download path from being handed non-URL payloads.
Source
Thrown at clis/minimax/utils.js:140
}
function parseExpectedSize(extraInfo) {
if (!extraInfo || typeof extraInfo !== 'object' || Array.isArray(extraInfo)) {
throw new CommandExecutionError('MiniMax music returned malformed extra_info');
}
if (extraInfo.music_size == null) return null;
if (!Number.isSafeInteger(extraInfo.music_size) || extraInfo.music_size <= 0) {
throw new CommandExecutionError('MiniMax music returned invalid extra_info.music_size');
}
return extraInfo.music_size;
}
export function requireAudioUrl(value) {
let url;
try {
url = new URL(value);
} catch {
throw new CommandExecutionError('MiniMax music returned data.audio that is not a URL');
}
if (url.protocol !== 'https:') {
throw new CommandExecutionError(`MiniMax music returned a non-HTTPS audio URL (${url.protocol})`);
}
return url.toString();
}
export function decodeAudioHex(value, expectedBytes, format) {
if (value.length === 0 || value.length % 2 !== 0 || !/^[0-9a-f]+$/i.test(value)) {
throw new CommandExecutionError('MiniMax music returned invalid hexadecimal audio');
}
const bytes = Buffer.from(value, 'hex');
if (expectedBytes != null && bytes.length !== expectedBytes) {
throw new CommandExecutionError(`MiniMax music audio size mismatch (expected ${expectedBytes} bytes, got ${bytes.length})`);
}
if (format === 'wav' && (bytes.length < 12 || bytes.subarray(0, 4).toString('ascii') !== 'RIFF' || bytes.subarray(8, 12).toString('ascii') !== 'WAVE')) {
throw new CommandExecutionError('MiniMax music returned bytes that are not a WAV file');
}View on GitHub (pinned to 49907e53dc)
Solutions
- Check whether data.audio looks like hex (matches /^[0-9a-f]+$/i) and use decodeAudioHex instead of requireAudioUrl
- If it's a relative path, prefix the MiniMax CDN base URL before parsing
- Log the value to confirm what form the audio actually takes
- Ensure you call the right handler for your endpoint variant (URL vs hex payload)
Example fix
// before
const url = requireAudioUrl(data.audio);
// after
if (/^[0-9a-f]+$/.test(data.audio)) {
const bytes = decodeAudioHex(data.audio, expectedBytes, format);
} else {
const url = requireAudioUrl(data.audio.startsWith('/') ? BASE + data.audio : data.audio);
} Defensive patterns
Strategy: type-guard
Validate before calling
function isHttpUrl(v) {
try { const u = new URL(v); return u.protocol === 'http:' || u.protocol === 'https:'; }
catch { return false; }
}
if (!isHttpUrl(payload?.data?.audio)) {
// route to hex/base64 decode path instead
} Type guard
function isAbsoluteUrl(v) {
if (typeof v !== 'string') return false;
try { new URL(v); return true; } catch { return false; }
} Try / catch
try {
const url = requireAudioUrl(data.audio);
} catch (e) {
if (/not a URL/.test(e.message)) {
// data.audio is likely hex or base64 — decode instead
const bytes = decodeAudioHex(data.audio, expectedBytes, format);
} else throw e;
} Prevention
- Detect payload form (URL vs hex) before choosing the handler
- Prefix relative paths with the MiniMax CDN base URL
- Validate response shape with fixtures from the live endpoint
- Keep URL-handling and hex-handling paths clearly separated in your code
When it happens
Trigger: The response's data.audio contains hex-encoded bytes (hex string parses as a URL scheme? no — URL() rejects it), a relative path like /audio/abc.mp3, base64 data, or an empty string; also when the endpoint switched from returning URLs to returning hex and the caller used the wrong handler.
Common situations: Calling requireAudioUrl on a response from an endpoint that returns hex audio instead of a URL; MiniMax returning a protocol-relative or relative URL; empty audio field slipping past an earlier check.
Related errors
- MiniMax music returned invalid hexadecimal audio
- MiniMax music response is missing integer data.status
- MiniMax music returned status 1 (in progress) without a resu
- MiniMax music returned unknown data.status ${data.status}
- MiniMax music reported completion without data.audio
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/b5fef683236fb0ad.
Report an issue: GitHub.