babysor/MockingBird · error · RuntimeError

/emotion-enhance returned no data: {resp.text}

Error message

/emotion-enhance returned no data: {resp.text}

What it means

Raised by call_emotion_enhance when /emotion-enhance returns HTTP 200 but the JSON payload lacks data.emotion_enhance or it is empty/falsy. This indicates a contract mismatch: the server responded successfully but with an unexpected schema or empty result.

Source

Thrown at skills/speak/scripts/noiz_tts.py:49

    return base64.b64encode(key.encode("utf-8")).decode("ascii")


def call_emotion_enhance(
    base_url: str, api_key: str, text: str, timeout: int
) -> str:
    resp = requests.post(
        f"{base_url.rstrip('/')}/emotion-enhance",
        headers={"Authorization": api_key, "Content-Type": "application/json"},
        json={"text": text},
        timeout=timeout,
    )
    if resp.status_code != 200:
        raise RuntimeError(
            f"/emotion-enhance failed: status={resp.status_code}, body={resp.text}"
        )
    enhanced = resp.json().get("data", {}).get("emotion_enhance")
    if not enhanced:
        raise RuntimeError(f"/emotion-enhance returned no data: {resp.text}")
    return enhanced


def synthesize(
    base_url: str,
    api_key: str,
    text: str,
    voice_id: Optional[str],
    reference_audio: Optional[Path],
    output_format: str,
    speed: float,
    emo: Optional[str],
    target_lang: Optional[str],
    similarity_enh: bool,
    save_voice: bool,
    duration: Optional[float],
    timeout: int,
    out_path: Path,

View on GitHub (pinned to 28dc5e14f1)

Solutions

  1. Print/inspect resp.text to see the actual payload shape
  2. Verify you are on the API version whose responses include data.emotion_enhance
  3. Guard upstream: reject empty text before calling the endpoint
  4. Fall back to the original text when enhancement is unavailable

Example fix

# before
enhanced = resp.json().get("data", {}).get("emotion_enhance")
if not enhanced:
    raise RuntimeError(f"/emotion-enhance returned no data: {resp.text}")
# after (graceful fallback)
enhanced = resp.json().get("data", {}).get("emotion_enhance") or text
Defensive patterns

Strategy: fallback

Validate before calling

assert text and text.strip(), 'text required before emotion enhance'

Try / catch

try:
    enhanced = call_emotion_enhance(...)
except RuntimeError as e:
    if 'returned no data' in str(e):
        enhanced = text  # graceful fallback
    else:
        raise

Prevention

When it happens

Trigger: POST /emotion-enhance returns 200 with body missing the "data" key, missing "emotion_enhance" inside it, or an empty string — e.g. server version change, empty input text echoed back, or an HTML/error page that happens to parse as JSON.

Common situations: API version drift where the response schema changed, gateway returning an empty JSON envelope, or passing blank text after strip().

Related errors


AI-assisted analysis of babysor/MockingBird@28dc5e14f1 (2026-08-27). Data as JSON: /api/errors/1cffadf5372cb25e. Report an issue: GitHub.