calesthio/OpenMontage · error · ToolCommandError
{detail}
Error message
{detail} What it means
Raised by BaseTool.run_command when a subprocess it launched exits non-zero: subprocess.run(..., check=True) raises CalledProcessError, which is wrapped into ToolCommandError carrying returncode, cmd, output, and stderr. The detail is stderr if present, else stdout, else str(exc) — so the message you see is the underlying command's own error text, not a library string. ToolCommandError subclasses subprocess.CalledProcessError, so standard attributes (returncode, cmd, stdout, stderr) are available for programmatic handling.
Source
Thrown at tools/base_tool.py:447
return subprocess.run(
resolved_cmd,
capture_output=True,
text=True,
# Force UTF-8 decoding. The default uses the OS locale (cp1252 on
# Windows), which raises UnicodeDecodeError on a subprocess that
# emits Unicode/emoji (e.g. Remotion's progress output), killing the
# reader thread and potentially swallowing the real error text.
encoding="utf-8",
errors="replace",
timeout=timeout,
cwd=cwd,
check=True,
)
except subprocess.CalledProcessError as exc:
stderr = (exc.stderr or "").strip()
stdout = (exc.stdout or "").strip()
detail = stderr or stdout or str(exc)
raise ToolCommandError(
exc.returncode,
exc.cmd,
output=exc.output,
stderr=exc.stderr,
detail=detail,
) from exc
class ToolCommandError(subprocess.CalledProcessError):
"""CalledProcessError with stderr/stdout surfaced in str(error)."""
def __init__(
self,
returncode: int,
cmd: list[str],
*,
output: Optional[str] = None,
stderr: Optional[str] = None,View on GitHub (pinned to 95e1c3d0ab)
Solutions
- Read e.stderr/e.stdout from the caught ToolCommandError — they contain the actual command diagnostics
- Reproduce manually: run e.cmd in a shell with the same arguments to iterate quickly
- Fix the concrete underlying issue (input file, codec, flags, permissions, disk space)
- Pin or adapt to the external tool's version if flags changed; never retry blindly on deterministic argument errors
Example fix
# before
try:
tool.run_command(["ffmpeg", "-i", src, out])
except ToolCommandError as e:
raise RuntimeError(f"command failed: {e}") # loses diagnostics
# after
try:
tool.run_command(["ffmpeg", "-i", src, out])
except ToolCommandError as e:
log.error("cmd=%s rc=%s stderr=%s", e.cmd, e.returncode, (e.stderr or "").strip())
raise Defensive patterns
Strategy: try-catch
Validate before calling
import shutil
if not shutil.which(cmd[0]):
raise SystemExit(f"command {cmd[0]} not installed")
for f in input_files:
if not Path(f).is_file():
raise SystemExit(f"input missing: {f}") Try / catch
from tools.base_tool import ToolCommandError
try:
tool.run_command(cmd)
except ToolCommandError as e:
log.error("cmd=%s rc=%s\nstderr=%s", e.cmd, e.returncode, (e.stderr or "").strip())
if e.returncode in (13,): # deterministic permission error: do not retry
raise
if is_transient(e): # e.g. network-flaky downloader
return tool.run_command(cmd) # single retry
raise Prevention
- Always log e.stderr/e.returncode — the underlying command's diagnostics are attached
- Reproduce the failing e.cmd manually before changing code
- Guard against retrying deterministic failures (bad arguments, missing files); retry only transient ones
- Check output directory permissions and disk space before long renders
When it happens
Trigger: Any tool shelling out to ffmpeg/ffprobe/node/CLI binaries with invalid arguments, unreadable input files, unsupported codecs, or write-permission failures on the output path. E.g. ffmpeg exiting 1 on a corrupt input surfaces its stderr here.
Common situations: Bad file paths or codec mismatches passed to ffmpeg; a CLI tool's version changing its flags; disk-full or permission-denied on output; non-UTF8 output already mitigated by errors='replace', so the real error text survives; command timeouts surface separately.
Related errors
- Checkpoint artifacts must be a dictionary
- ffmpeg failed to render preview MP4
- Invalid status: {status!r}
- Checkpoint failed schema validation: {exc.message}
- Unknown demo '{args.demo}'. Available demos: {available}
AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15).
Data as JSON: /api/errors/4964008816193d02.
Report an issue: GitHub.