Comfy-Org/ComfyUI · error · ValueError
HeyGen did not return an audio_url: {response}
Error message
HeyGen did not return an audio_url: {response} What it means
Thrown by HeyGen text-to-speech when the POST to the speech endpoint returns no data.audio_url. The request (text/ssml, voice_id, speed) was accepted HTTP-wise but the response lacks the synthesizable artifact URL; the whole response is embedded in the error for diagnosis.
Source
Thrown at comfy_api_nodes/nodes_heygen.py:781
ssml: bool = False,
seed: int = 0,
) -> IO.NodeOutput:
validate_string(text, strip_whitespace=True, min_length=1, max_length=5000)
payload = {
"text": text,
"voice_id": custom_voice_id.strip() or HEYGEN_VOICE_TTS_MAP[voice],
"speed": round(speed, 2),
}
if ssml:
payload["input_type"] = "ssml"
response = await sync_op_raw(
cls,
ApiEndpoint(path=_SPEECH_PATH, method="POST"),
data=payload,
)
audio_url = (response.get("data") or {}).get("audio_url")
if not audio_url:
raise ValueError(f"HeyGen did not return an audio_url: {response}")
audio_bytes = await download_url_as_bytesio(audio_url)
return IO.NodeOutput(audio_bytes_to_audio_input(audio_bytes.getvalue()))
class HeyGenExtension(ComfyExtension):
@override
async def get_node_list(self) -> list[type[IO.ComfyNode]]:
return [
HeyGenTalkingPhotoNode,
HeyGenAvatarVideoNode,
HeyGenCreateAvatarNode,
HeyGenVideoTranslateNode,
HeyGenTextToSpeechNode,
]
async def comfy_entrypoint() -> HeyGenExtension:
return HeyGenExtension()View on GitHub (pinned to 1c6d8d45b3)
Solutions
- Read the response body in the message — HeyGen's error text names the bad field
- Use a voice from the dropdown or verify the custom voice_id exists in your workspace
- Validate SSML against HeyGen's documented subset, or disable ssml mode for plain text
- Check account TTS credits
Defensive patterns
Strategy: try-catch
Validate before calling
def tts_payload_ok(voice: str, custom_voice_id: str, ssml: bool) -> bool:
return bool(custom_voice_id.strip() or voice in HEYGEN_VOICE_TTS_MAP) Try / catch
try:
audio = await tts(...)
except ValueError as e:
if 'did not return an audio_url' in str(e):
# check embedded response: bad voice_id / SSML / credits
raise Prevention
- Use dropdown voices or workspace-verified custom voice ids
- Test SSML snippets with plain text first to isolate dialect errors
When it happens
Trigger: HeyGen returns an error payload: invalid voice_id (custom id typo, or voice missing from HEYGEN_VOICE_TTS_MAP mapping), malformed SSML when input_type=ssml, quota/auth failure, or schema change moving audio_url.
Common situations: Custom voice ids pasted with whitespace or from a different HeyGen workspace; SSML that does not comply with HeyGen's Starfish TTS dialect; expired credentials.
Related errors
- A voice is required when driving the video with a text scrip
- HeyGen did not return a video_id: {created}
- HeyGen did not return an avatar: {created}
- HeyGen did not return a translation ID: {created}
- DurationHead requires at least one of video_tokens / audio_t
AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14).
Data as JSON: /api/errors/6f78316e7d5fc1a7.
Report an issue: GitHub.