Yalantis/uCrop · error · CImgInstanceException

save_video(): Instance list is empty.

Error message

save_video(): Instance list is empty.

What it means

Guard in CImgList<T>::save_video(): the frame list supplied for encoding is empty, so there are no images to write into the video stream; the writer checks list size before pushing frames to the OpenCV video writer.

Solutions

  1. Check list.is_empty() (or size()>0) before calling save_video
  2. Ensure the capture loop actually pushed frames into the list
  3. Guard the save behind 'if (frames) frames.save_video(...)': skip or log otherwise

Example fix

// before
frames.save_video("out.avi", 25); // frames may be empty
// after
if (!frames.is_empty()) frames.save_video("out.avi", 25);
Defensive patterns

Strategy: validation

Validate before calling

// C++
if (frames.is_empty()) return; // or log

Type guard

bool hasFrames(const CImgList<T>& l) { return !l.is_empty(); }

Try / catch

try { frames.save_video(fname, fps, codec); }
catch (CImgInstanceException& e) { log("no frames to encode"); }

Prevention

When it happens

Trigger: Calling save_video(filename,...) on a CImgList constructed empty, cleared, or whose frames were all moved out (e.g. via move_to) before the save.

Common situations: Capture loop that never appended frames (camera read failure) then attempted save; calling save_video after filtering/emptying the list.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08). Data as JSON: /api/errors/bf1ffaa684989194. Report an issue: GitHub.

Appendix: source

Thrown at ucrop/src/main/jni/CImg.h:68579

            }
        } else index = last_used_index;
        cimg::mutex(9,0);

        // Find empty slot for capturing video stream.
        if (index<0) {
          if (!filename)
            throw CImgArgumentException(_cimglist_instance
                                        "save_video(): No already open video writer found. You must specify a "
                                        "non-(null) filename argument for the first call.",
                                        cimglist_instance);
          else { cimg::mutex(9); cimglist_for(filenames,l) if (!filenames[l]) { index = l; break; } cimg::mutex(9,0); }
          if (index<0)
            throw CImgIOException(_cimglist_instance
                                  "save_video(): File '%s', no video writer slots available. "
                                  "You have to release some of your previously opened videos.",
                                  cimglist_instance,filename);
          if (is_empty())
            throw CImgInstanceException(_cimglist_instance
                                        "save_video(): Instance list is empty.",
                                        cimglist_instance);
          const unsigned int W = _data?_data[0]._width:0, H = _data?_data[0]._height:0;
          if (!W || !H)
            throw CImgInstanceException(_cimglist_instance
                                        "save_video(): Frame [0] is an empty image.",
                                        cimglist_instance);
          const char
            *const _codec = codec && *codec?codec:"h264",
            codec0 = cimg::uppercase(_codec[0]),
            codec1 = _codec[0]?cimg::uppercase(_codec[1]):0,
            codec2 = _codec[1]?cimg::uppercase(_codec[2]):0,
            codec3 = _codec[2]?cimg::uppercase(_codec[3]):0;
          cimg::mutex(9);
          writers[index] = new cv::VideoWriter(filename,_cimg_fourcc(codec0,codec1,codec2,codec3),fps,cv::Size(W,H));
          if (!writers[index]->isOpened()) {
            delete writers[index];
            writers[index] = 0;

View on GitHub (pinned to f788b534b4)