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

  1. Check whether data.audio looks like hex (matches /^[0-9a-f]+$/i) and use decodeAudioHex instead of requireAudioUrl
  2. If it's a relative path, prefix the MiniMax CDN base URL before parsing
  3. Log the value to confirm what form the audio actually takes
  4. 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

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


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/b5fef683236fb0ad. Report an issue: GitHub.