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

  1. Check the file with ffprobe -i <file_path>; treat unreadable/empty files as corrupt
  2. Skip or delete zero-byte and truncated videos before extraction
  3. Recover the video from a backup or trigger re-recording
  4. 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

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


AI-assisted analysis of screenpipe/screenpipe@4ebf712990 (2026-09-01). Data as JSON: /api/errors/145926788f1501c4. Report an issue: GitHub.