MiniMax-AI/skills · error · SystemExit

API Error [{base_resp.get('status_code')}]: {base_resp.get('

Error message

API Error [{base_resp.get('status_code')}]: {base_resp.get('status_msg')}

What it means

The POST to {API_BASE}/t2a_v2 returned HTTP 2xx (raise_for_status passed) but the body's base_resp.status_code is non-zero — an application-level TTS error. status_msg carries the detail. This is the same base_resp contract as the other MiniMax endpoints.

Source

Thrown at skills/frontend-dev/scripts/minimax_tts.py:81

        "output_format": "hex",
    }

    resp = requests.post(
        f"{API_BASE}/t2a_v2",
        headers={
            "Authorization": f"Bearer {API_KEY}",
            "Content-Type": "application/json",
        },
        json=payload,
        timeout=timeout,
    )
    resp.raise_for_status()
    data = resp.json()

    # Check API-level error
    base_resp = data.get("base_resp", {})
    if base_resp.get("status_code", 0) != 0:
        raise SystemExit(f"API Error [{base_resp.get('status_code')}]: {base_resp.get('status_msg')}")

    audio_hex = data.get("data", {}).get("audio", "")
    if not audio_hex:
        raise SystemExit(f"No audio in response: {json.dumps(data, indent=2)}")

    return bytes.fromhex(audio_hex)


def main():
    p = argparse.ArgumentParser(description="MiniMax Sync TTS (HTTP)")
    p.add_argument("text", help="Text to synthesize (max 10000 chars)")
    p.add_argument("-o", "--output", required=True, help="Output file path")
    p.add_argument("-v", "--voice", default="male-qn-qingse", help="Voice ID")
    p.add_argument("--model", default="speech-2.8-hd", help="Model (default: speech-2.8-hd)")
    p.add_argument("--speed", type=float, default=1.0, help="Speed 0.5-2.0")
    p.add_argument("--volume", type=float, default=1.0, help="Volume 0.1-10")
    p.add_argument("--pitch", type=int, default=0, help="Pitch -12 to 12")
    p.add_argument("--emotion", default="", help="Emotion tag (happy/sad/angry/...)")

View on GitHub (pinned to 60aaae52bb)

Solutions

  1. Read status_code/status_msg — they pin the cause (e.g. invalid param, length, content, rate limit).
  2. Clamp/validate inputs before sending: text ≤10000 chars, speed 0.5–2.0, volume 0.1–10, pitch -12..12.
  3. Confirm the voice_id and model are a valid pairing for your account/region.
  4. Match the API_BASE region to the key region and retry on transient rate-limit codes after backoff.

Example fix

// before: send unchecked user text straight to the API
tts(text=user_text, voice_id=vid)

// after: validate bounds to avoid a base_resp rejection
if len(user_text) > 10000:
    raise ValueError("text exceeds 10000 chars")
if not (0.5 <= speed <= 2.0) or not (0.1 <= volume <= 10):
    raise ValueError("speed/volume out of range")
tts(text=user_text[:10000], voice_id=vid, speed=speed, volume=volume)
Defensive patterns

Strategy: try-catch

Validate before calling

def validate_tts(text, voice_id, speed, volume, pitch, model="speech-2.8-hd"):
    assert len(text) <= 10000, "text > 10000 chars"
    assert 0.5 <= speed <= 2.0, "speed out of 0.5-2.0"
    assert 0.1 <= volume <= 10, "volume out of 0.1-10"
    assert -12 <= pitch <= 12, "pitch out of -12..12"
    assert voice_id, "voice_id required"
    assert model, "model required"

Type guard

def is_api_error(data: dict) -> bool:
    base = data.get("base_resp", {}) if isinstance(data, dict) else {}
    return isinstance(base, dict) and base.get("status_code", 0) != 0

Try / catch

import subprocess, sys
try:
    subprocess.run([sys.executable, "minimax_tts.py", text, "-o", out, "-v", vid], check=True, capture_output=True, text=True)
except subprocess.CalledProcessError as e:
    msg = (e.stderr or "") + (e.stdout or "")
    if "API Error [" in msg:
        code, detail = parse_api_error(msg)
        if code in TRANSIENT_CODES:
            time.sleep(backoff); retry()
        else:
            raise RuntimeError(f"tts API {code}: {detail}") from e
    raise

Prevention

When it happens

Trigger: Invalid voice_id; text longer than 10000 chars; speed outside 0.5–2.0; volume outside 0.1–10; pitch outside -12..12; an unsupported emotion value; an invalid sample_rate/bitrate/format combination for the chosen model; unsupported language_boost; content-policy rejection of the text; rate limit or quota.

Common situations: Passing a voice_id from a different model tier than speech-2.8-hd; requesting wav/flac with a sample_rate the model doesn't support; emotion tag spelled wrong; long text exceeding the 10000-char ceiling; region/key mismatch (overseas key vs mainland host).

Related errors


AI-assisted analysis of MiniMax-AI/skills@60aaae52bb (2026-08-13). Data as JSON: /api/errors/8c2a34107ead2414. Report an issue: GitHub.