affaan-m/ECC · error · RuntimeError
Decoder produced a truncated frame
Error message
Decoder produced a truncated frame
What it means
transform_stream reads raw RGB frames from the ffmpeg decoder's stdout in exact frame_bytes chunks. If a read returns a partial chunk (neither empty nor a full frame), the frame would be malformed, so it raises RuntimeError('Decoder produced a truncated frame'). This guards against ffmpeg dying mid-frame or a pipe returning short reads.
Solutions
- Validate the source media integrity first (ffprobe / try a full decode pass: ffmpeg -v error -i src -f null -)
- Check ffmpeg's stderr for the real failure (codec errors, OOM kill, signal)
- Re-encode/re-mux the input to a well-formed intermediate file before applying the glitch effect
- Re-run; transient kills (OOM) may pass on a machine with more free memory or a lower width/height
Example fix
// before
render('truncated.mp4', ...) # dies mid-frame
// after
subprocess.run(['ffmpeg','-v','error','-y','-i','truncated.mp4','-c','copy','fixed.mp4'])
render('fixed.mp4', ...) Defensive patterns
Strategy: validation
Validate before calling
import subprocess r = subprocess.run(['ffmpeg','-v','error','-i', src,'-f','null','-'], capture_output=True) assert r.returncode == 0, r.stderr.decode()
Try / catch
try:
render(src, 0, out)
except RuntimeError as e:
if 'truncated frame' in str(e):
# re-mux or re-encode source before retrying
... Prevention
- Pre-flight full decode of the source (ffmpeg -v error -i src -f null -)
- Keep sufficient free memory; large width/height frames can OOM the decoder
- Avoid truncated downloads — verify checksums of source media
- Reduce output resolution if the machine is memory-constrained
When it happens
Trigger: ffmpeg decoder process exits or is killed between full frames; a partial read from dec.stdout that returns fewer bytes than frame_bytes; corrupted/truncated source media ending mid-frame.
Common situations: ffmpeg crashing mid-decode (OOM, bad packet); source file truncated on disk; decoding a file whose advertised size exceeds actual bytes; platform pipe buffering edge cases.
Related errors
- Decoder produced no frames
- Media command produced an empty output
- apply_local needs at least one media clip
- asset contains too few frames
- asset requires verified alpha
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/485945b9bf12a674.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/media/glitch.py:64
zoomed = np.asarray(z.crop((x0, y0, x0 + width, y0 + height)), dtype=np.float32)
decay = 0.90 + 0.06 * p
acc = np.maximum(f.astype(np.float32), zoomed * decay)
return acc.astype(np.uint8)
def fx_drift(f, p):
# subtle horizontal shift + RGB separation, very light
shift = int(rng.integers(2, 18) * p) * (1 if rng.random() < 0.5 else -1)
f = f.copy()
f[:, :, 0] = np.roll(f[:, :, 0], shift, axis=1)
f[:, :, 2] = np.roll(f[:, :, 2], -shift // 2, axis=1)
return f
while True:
buf = dec.stdout.read(frame_bytes)
if not buf:
break
if len(buf) != frame_bytes:
raise RuntimeError("Decoder produced a truncated frame")
f = np.frombuffer(buf, np.uint8).reshape(height, width, 3).copy()
total = max(1, int(duration * fps))
p = min(1.0, (n + 1) / (total * 0.6))
if mode == "pixelsort":
out = fx_pixelsort(f, p)
elif mode == "feedback":
out = fx_feedback(f, p)
elif mode == "drift":
out = fx_drift(f, p)
else:
# very light mosh
out = f
y = 0
while y < height:
bh = int(rng.integers(8, 28))
if rng.random() < 0.12 * p:
shift = int(rng.integers(4, 40) * p) * (View on GitHub (pinned to 8321021c54)