ATH-MaaS/Pixelle-Video · error · Exception
No audio file generated by workflow
Error message
No audio file generated by workflow
What it means
Even when the TTS workflow completes, _call_comfyui_workflow must find an audio file. It probes result.audios, then result.files, then scans result.outputs for strings ending in .mp3/.wav/.flac. If none yields a path it raises 'No audio file generated by workflow' after dumping the full result to logs. This indicates a completed run with no recognizable audio output.
Source
Thrown at pixelle_video/services/tts_service.py:292
logger.debug(f"✅ Found audio in result.files: {audio_path}")
# Check in outputs dictionary
elif hasattr(result, 'outputs') and result.outputs:
logger.debug(f"Searching for audio file in result.outputs: {result.outputs}")
# Try to find audio file in outputs
for key, value in result.outputs.items():
if isinstance(value, str) and any(value.endswith(ext) for ext in ['.mp3', '.wav', '.flac']):
audio_path = value
logger.debug(f"✅ Found audio in result.outputs[{key}]: {audio_path}")
break
if not audio_path:
logger.error("No audio file generated")
logger.error(f"❌ Result analysis:")
logger.error(f" - result.audios: {getattr(result, 'audios', 'NOT_FOUND')}")
logger.error(f" - result.files: {getattr(result, 'files', 'NOT_FOUND')}")
logger.error(f" - result.outputs: {getattr(result, 'outputs', 'NOT_FOUND')}")
logger.error(f" - Full __dict__: {result.__dict__}")
raise Exception("No audio file generated by workflow")
# If output_path provided and audio_path is URL, download to local
if output_path and audio_path.startswith(('http://', 'https://')):
import httpx
import os
# Ensure parent directory exists
os.makedirs(os.path.dirname(output_path), exist_ok=True)
logger.info(f"Downloading audio from {audio_path} to {output_path}")
async with httpx.AsyncClient() as client:
response = await client.get(audio_path)
response.raise_for_status()
with open(output_path, 'wb') as f:
f.write(response.content)
logger.info(f"✅ Generated audio (ComfyUI): {output_path}")View on GitHub (pinned to 848b054e4f)
Solutions
- Check the logged 'Result analysis' block (result.audios/files/outputs and full __dict__) to see exactly where the audio landed; adapt extraction to that shape.
- Ensure the workflow has an enabled audio output node and that RunningHub exposes it as an output file.
- If the audio is saved with another extension (.ogg, .opus), extend the outputs scan's extension list or normalize the workflow to emit .mp3/.wav.
- If outputs nest the URL inside a dict, update extraction to unwrap the value (e.g. value['url']) instead of requiring a bare string.
- Upgrade ComfyKit if your version predates first-class audios support in its result object.
Example fix
// before
for key, value in result.outputs.items():
if isinstance(value, str) and any(value.endswith(ext) for ext in ['.mp3', '.wav', '.flac']):
audio_path = value
// after
AUDIO_EXTS = ('.mp3', '.wav', '.flac', '.ogg', '.opus')
for key, value in result.outputs.items():
if isinstance(value, dict):
value = value.get('url') or value.get('path')
if isinstance(value, str) and value.endswith(AUDIO_EXTS):
audio_path = value
break Defensive patterns
Strategy: type-guard
Validate before calling
# pre-flight: workflow must have an enabled audio output node
def workflow_produces_audio(workflow_json: dict) -> bool:
nodes = workflow_json.get("nodes", [])
return any("SaveAudio" in n.get("type", "") or "AudioCombine" in n.get("type", "")
for n in nodes if not n.get("mode"))
assert workflow_produces_audio(load_workflow(tts_workflow_key)) Type guard
def extract_audio_path(result) -> str | None:
audios = getattr(result, "audios", None)
if audios:
return audios[0]
files = getattr(result, "files", None)
if files:
return files[0]
for v in (getattr(result, "outputs", None) or {}).values():
if isinstance(v, dict):
v = v.get("url") or v.get("path")
if isinstance(v, str) and v.endswith((".mp3", ".wav", ".flac", ".ogg", ".opus")):
return v
return None Try / catch
try:
audio = await tts_service(...)
except Exception as e:
if "No audio file generated" in str(e):
logger.error("TTS workflow produced no audio; inspect output node config and result schema")
raise WorkflowConfigError("TTS workflow has no recognizable audio output") from e
raise Prevention
- Keep an enabled audio save node in every TTS workflow and expose it on RunningHub.
- Standardize output extensions to .mp3/.wav/.flac, or widen extraction to cover .ogg/.opus.
- After ComfyKit upgrades, verify where audio appears in the result object (schema drift).
- Log result.__dict__ on empty outputs — the service already dumps it; alert on that log line.
- Smoke-test TTS workflows in CI so output-node regressions are caught before production.
When it happens
Trigger: result.status == 'completed' but result.audios, result.files are empty/missing and result.outputs contains no string ending in .mp3/.wav/.flac — e.g. the workflow saves audio under a different extension (.ogg, .opus), the audio save node is bypassed, or outputs are nested dicts rather than plain strings.
Common situations: TTS node writes non-standard formats the extension scan misses; ComfyKit version whose result schema stores audio elsewhere (e.g. result.outputs['audio'] as a dict with 'url' key); RunningHub workflow without an exposed audio output node; SaveAudio node disabled in the graph.
Related errors
- No video generated
- No image generated
- str(e)
- TTS generation failed: {error_msg}
- 参考音频不存在: {reference_audio_path}
AI-assisted analysis of ATH-MaaS/Pixelle-Video@848b054e4f (2026-08-30).
Data as JSON: /api/errors/b38586239b08bc26.
Report an issue: GitHub.