Comfy-Org/ComfyUI · error · Exception

Sonilo API error ({resp.status}): {msg}

Error message

Sonilo API error ({resp.status}): {msg}

What it means

Raised by the Sonilo node when the initial HTTP POST to the Sonilo endpoint returns a status >= 400. The response body is parsed by _extract_error_message (looking for a JSON `detail` field) and embedded into the raised message. This is the entry-point failure for the streaming NDJSON music generation call.

Source

Thrown at comfy_api_nodes/nodes_sonilo.py:183

    """POST ``form`` to Sonilo, read the NDJSON stream, and return the first stream's audio bytes."""
    url = urljoin(default_base_url().rstrip("/") + "/", endpoint.path.lstrip("/"))

    headers = get_comfy_api_headers(cls)
    headers.update(endpoint.headers)

    node_id = get_node_id(cls)
    start_ts = time.monotonic()
    last_chunk_status_ts = 0.0
    audio_streams: dict[int, list[bytes]] = {}
    title: str | None = None

    timeout = aiohttp.ClientTimeout(total=1200.0, sock_read=300.0)
    async with aiohttp.ClientSession(timeout=timeout) as session:
        PromptServer.instance.send_progress_text("Status: Queued", node_id)
        async with session.post(url, data=form, headers=headers) as resp:
            if resp.status >= 400:
                msg = await _extract_error_message(resp)
                raise Exception(f"Sonilo API error ({resp.status}): {msg}")

            while True:
                if is_processing_interrupted():
                    raise ProcessingInterrupted("Task cancelled")

                raw_line = await resp.content.readline()
                if not raw_line:
                    break

                line = raw_line.decode("utf-8").strip()
                if not line:
                    continue

                try:
                    evt = json.loads(line)
                except json.JSONDecodeError:
                    logger.warning("Sonilo: skipping malformed NDJSON line")
                    continue

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Check the embedded msg and status: 401/403 means fix the API key/headers, 422 means fix form parameters
  2. Verify the Sonilo endpoint URL is current
  3. For 5xx, wait and retry — server-side issue
Defensive patterns

Strategy: try-catch

Validate before calling

headers["Authorization"] = f"Bearer {os.environ['SONILO_API_KEY']}"  # fail fast if key missing
assert form is not None and url.startswith("https://"), "valid Sonilo endpoint and form required"

Try / catch

try:
    audio = await _sonilo_generate(url, form, headers)
except Exception as e:
    msg = str(e)
    if "Sonilo API error (401)" in msg or "(403)" in msg:
        refresh_sonilo_credentials()
    elif "(4" in msg:
        raise ValueError(f"Bad Sonilo request: {msg}") from e
    else:
        raise

Prevention

When it happens

Trigger: POSTing the multipart form to the Sonilo API url with an expired/invalid token, malformed form fields, or a server-side error, yielding HTTP 4xx/5xx; _extract_error_message then formats the body.

Common situations: Invalid or expired Sonilo API key/headers; wrong endpoint url; prompt or parameter rejected with 422; Sonilo service outage returning 5xx.

Related errors


AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14). Data as JSON: /api/errors/d935be79eda65229. Report an issue: GitHub.