ytdl-org/youtube-dl · error · PostProcessingError
Command returned error code %d
Error message
Command returned error code %d
What it means
Raised by ExecAfterDownloadPP (--exec CMD) when the executed shell command exits with a non-zero status. The message includes the actual exit code. The command runs through the shell with the filepath substituted for '{}', so any failure inside the user-supplied command surfaces here.
Source
Thrown at youtube_dl/postprocessor/execafterdownload.py:28
)
class ExecAfterDownloadPP(PostProcessor):
def __init__(self, downloader, exec_cmd):
super(ExecAfterDownloadPP, self).__init__(downloader)
self.exec_cmd = exec_cmd
def run(self, information):
cmd = self.exec_cmd
if '{}' not in cmd:
cmd += ' {}'
cmd = cmd.replace('{}', compat_shlex_quote(information['filepath']))
self._downloader.to_screen('[exec] Executing command: %s' % cmd)
retCode = subprocess.call(encodeArgument(cmd), shell=True)
if retCode != 0:
raise PostProcessingError(
'Command returned error code %d' % retCode)
return [], information
View on GitHub (pinned to 956b8c5855)
Solutions
- Run the printed command manually ('[exec] Executing command: ...' line) with the same file to see the real failure
- Fix quoting: keep '{} ' inside quotes if paths contain spaces, e.g. --exec 'mv "{}" /dst/'
- Make the command exit 0 on success — append '|| true' only if failure is genuinely acceptable
- Ensure the command exists on PATH in the environment youtube-dl runs in
Example fix
# before
youtube-dl --exec 'ffmpeg -i {} out.mp4' URL
# after (quoted target, explicit exit handling)
youtube-dl --exec 'ffmpeg -i "{}" "{}.mp4" && echo done' URL Defensive patterns
Strategy: try-catch
Validate before calling
import shutil
def exec_hook_runnable(cmd):
base = cmd.split()[0]
return shutil.which(base) is not None
assert exec_hook_runnable(opts['exec_cmd']), 'exec hook binary not on PATH' Try / catch
try:
ydl.download([url])
except PostProcessingError as e:
if 'Command returned error code' in str(e):
log.warning('post-download hook failed for %s (check --exec command)', information_path) Prevention
- Test the --exec command manually with a sample path before batch use
- Quote '{}' inside the hook so paths with spaces stay one shell word
- Remember the file IS downloaded — a failing hook need not discard the result
When it happens
Trigger: Passing --exec 'rm {} && notify-send done' where a step fails (nonexistent file, permission denied, typo'd command); commands that assume a different cwd; commands whose last statement returns non-zero (e.g. grep with no match).
Common situations: Hooking --exec into scripts to move files, call ffmpeg again, or fire desktop notifications; quoting mistakes so '{}' splits into multiple shell words; commands valid in zsh but not sh.
Related errors
- AtomicParsley was not found. Please install.
- stderr.decode('utf-8', 'replace').strip() (dynamic AtomicPar
- Only mp3 and m4a/mp4 are supported for thumbnail embedding f
- ffmpeg or avconv not found. Please install one.
- ffprobe/avprobe and ffmpeg/avconv not found. Please install
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/b5cb4bb84a208bee.
Report an issue: GitHub.