screenpipe/screenpipe · error
VIDEO_CORRUPTED: cannot read metadata from {} and no frame w
Error message
VIDEO_CORRUPTED: cannot read metadata from {} and no frame was produced What it means
Raised when ffmpeg exited successfully but the expected output frame file does not exist, and the video's metadata was already found unreadable. It is the VIDEO_CORRUPTED counterpart of error 503: the source video is almost certainly unplayable, so ffmpeg 'succeeded' without producing any decodable frame.
Source
Thrown at crates/screenpipe-engine/src/video_utils.rs:1209
let output = command.output().await?;
if !output.status.success() {
let error_message = String::from_utf8_lossy(&output.stderr);
info!("ffmpeg error: {}", error_message);
if metadata_unreadable {
return Err(anyhow::anyhow!(
"VIDEO_CORRUPTED: cannot read metadata from {} and frame extraction failed: {}",
file_path,
error_message
));
}
return Err(anyhow::anyhow!("ffmpeg process failed: {}", error_message));
}
if !output_path.exists() {
if metadata_unreadable {
return Err(anyhow::anyhow!(
"VIDEO_CORRUPTED: cannot read metadata from {} and no frame was produced",
file_path
));
}
return Err(anyhow::anyhow!("failed to extract frame: file not created"));
}
// Schedule cleanup of old frames (files older than 1 hour)
tokio::spawn(async move {
if let Err(e) = cleanup_old_frames(&frames_dir).await {
error!("Failed to cleanup old frames: {}", e);
}
});
Ok(output_path.to_string_lossy().into_owned())
}
async fn cleanup_old_frames(frames_dir: &PathBuf) -> Result<()> {View on GitHub (pinned to 4ebf712990)
Solutions
- Check the file with ffprobe -i <file_path>; treat unreadable/empty files as corrupt
- Skip or delete zero-byte and truncated videos before extraction
- Recover the video from a backup or trigger re-recording
- Ensure no other process is truncating/moving files in the video directory
Example fix
// before
let frame = extract_frame_from_video(path, ts, &out).await?;
// after
if std::fs::metadata(path).map(|m| m.len() == 0).unwrap_or(true) {
skip_corrupt(path);
return Ok(None);
}
let frame = extract_frame_from_video(path, ts, &out).await?; Defensive patterns
Strategy: validation
Validate before calling
// Reject empty/unreadable videos up front
let md = std::fs::metadata(path)?;
if md.len() < 1024 { skip_corrupt(path); }
// or: ffprobe -v error <path> must succeed before extraction Try / catch
if let Err(e) = extract_frame_from_video(path, ts, dir).await {
if e.to_string().contains("VIDEO_CORRUPTED") {
mark_corrupt(path); // persistent skip-list
return Ok(None);
}
return Err(e.into());
} Prevention
- Skip-list files that fail this error instead of retrying forever
- Watch for zero-byte files appearing in the recordings directory (crashed writers)
- Verify media integrity after abnormal app shutdowns
When it happens
Trigger: extract_frame_from_video on a video whose metadata is unreadable; ffmpeg command returns status success but output_path is missing — typical for zero-byte or headerless/corrupt media files.
Common situations: Truncated recordings from power loss; 0-byte video files; container with no decodable video stream; antivirus or sync software interfering with file reads.
Related errors
- VIDEO_CORRUPTED: cannot read metadata from {} and frame extr
- failed to extract frame: file not created
- FFmpeg failed: {}
- Failed to open stdin for FFmpeg
- Gemini API request failed: ${response.status} ${error}
AI-assisted analysis of screenpipe/screenpipe@4ebf712990 (2026-09-01).
Data as JSON: /api/errors/145926788f1501c4.
Report an issue: GitHub.