microsoft/autogen · error · ValueError
audio_output_path must end with .mp3.
Error message
audio_output_path must end with .mp3.
What it means
extract_audio in video_surfer hard-codes MP3 output (ffmpeg format=mp3) and enforces it by rejecting any audio_output_path that does not end in .mp3 (case-insensitive). Allowing arbitrary extensions would let callers write other file types, so the extension acts as both a format contract and a write-scope guard (paired with a cwd path-traversal check).
Source
Thrown at python/packages/autogen-ext/src/autogen_ext/agents/video_surfer/tools.py:32
def extract_audio(video_path: str, audio_output_path: str) -> str:
"""
Extracts audio from a video file and saves it as an MP3 file.
:param video_path: Path to the video file (must be a local file path, not a URL).
:param audio_output_path: Path to save the extracted audio file (must end with .mp3).
:return: Confirmation message with the path to the saved audio file.
"""
import os
import re
# Reject URLs to prevent SSRF via ffmpeg
if re.match(r"^[a-zA-Z][a-zA-Z0-9+\-.]*://", video_path):
raise ValueError("video_path must be a local file path, not a URL.")
# Enforce .mp3 extension to prevent writing arbitrary file types
if not audio_output_path.lower().endswith(".mp3"):
raise ValueError("audio_output_path must end with .mp3.")
# Prevent path traversal — output must stay within the current working directory
cwd = os.path.realpath(os.getcwd())
output_real = os.path.realpath(audio_output_path)
if not output_real.startswith(cwd + os.sep) and output_real != cwd:
raise ValueError("audio_output_path must be within the current working directory.")
(ffmpeg.input(video_path).output(audio_output_path, format="mp3").run(quiet=True, overwrite_output=True)) # type: ignore
return f"Audio extracted and saved to {audio_output_path}."
def transcribe_audio_with_timestamps(audio_path: str) -> str:
"""
Transcribes the audio file with timestamps using the Whisper model.
:param audio_path: Path to the audio file.
:return: Transcription with timestamps.
"""View on GitHub (pinned to 027ecf0a37)
Solutions
- Rename the output to end with .mp3: pass "/tmp/out/clip.mp3".
- If you need another format, call ffmpeg directly (ffmpeg.input(...).output(path, format=...)) rather than this tool.
- In agent prompts, specify the output path convention *.mp3 for this tool.
Example fix
# before
extract_audio("/tmp/work/clip.mp4", "/tmp/work/clip.wav")
# after
extract_audio("/tmp/work/clip.mp4", "/tmp/work/clip.mp3") Defensive patterns
Strategy: validation
Validate before calling
import os
def mp3_output(path: str) -> str:
root, _ = os.path.splitext(path)
return root + ".mp3"
audio_out = mp3_output(audio_output_path) # always .mp3 Type guard
def is_mp3_path(p: str) -> bool:
return isinstance(p, str) and p.lower().endswith(".mp3") Prevention
- Derive output names by replacing the extension with .mp3, never reusing the input extension.
- For other formats, call ffmpeg directly instead of this tool.
- State the *.mp3 convention in agent instructions.
When it happens
Trigger: extract_audio("clip.mp4", "/tmp/out/clip.wav") — any output path whose lowercase form does not end with .mp3, including .MP3-safe variants like clip.mp4 or clip.
Common situations: LLM tool calls proposing .wav/.m4a outputs; pipelines that derive the output name from the input name without rewriting the extension.
Related errors
- audio_output_path must be within the current working directo
- video_path must be a local file path, not a URL.
- Timestamp {timestamp:.2f}s is out of range [0s, {duration:.2
- Failed to list MCP prompts
- Failed to get MCP prompt
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/3a2b98b12f7cb727.
Report an issue: GitHub.