{"record":{"id":"bd6a620e06a3f5e5","repo":"Yalantis/uCrop","slug":"save-video-no-already-open-video-writer-found","errorCode":null,"errorMessage":"save_video(): No already open video writer found. You must specify a non-(null) filename argument for the first call.","messagePattern":"save_video\\(\\): No already open video writer found\\. You must specify a non-\\(null\\) filename argument for the first call\\.","errorType":"exception","errorClass":"CImgArgumentException","httpStatus":null,"severity":"error","filePath":"ucrop/src/main/jni/CImg.h","lineNumber":68568,"sourceCode":"        static CImg<intT> sizes(32,2,1,1,0);\n        static int last_used_index = -1;\n\n        // Detect if a video writer already exists for the specified filename.\n        cimg::mutex(9);\n        int index = -1;\n        if (filename) {\n          if (last_used_index>=0 && !std::strcmp(filename,filenames[last_used_index])) {\n            index = last_used_index;\n          } else cimglist_for(filenames,l) if (filenames[l] && !std::strcmp(filename,filenames[l])) {\n              index = l; break;\n            }\n        } else index = last_used_index;\n        cimg::mutex(9,0);\n\n        // Find empty slot for capturing video stream.\n        if (index<0) {\n          if (!filename)\n            throw CImgArgumentException(_cimglist_instance\n                                        \"save_video(): No already open video writer found. You must specify a \"\n                                        \"non-(null) filename argument for the first call.\",\n                                        cimglist_instance);\n          else { cimg::mutex(9); cimglist_for(filenames,l) if (!filenames[l]) { index = l; break; } cimg::mutex(9,0); }\n          if (index<0)\n            throw CImgIOException(_cimglist_instance\n                                  \"save_video(): File '%s', no video writer slots available. \"\n                                  \"You have to release some of your previously opened videos.\",\n                                  cimglist_instance,filename);\n          if (is_empty())\n            throw CImgInstanceException(_cimglist_instance\n                                        \"save_video(): Instance list is empty.\",\n                                        cimglist_instance);\n          const unsigned int W = _data?_data[0]._width:0, H = _data?_data[0]._height:0;\n          if (!W || !H)\n            throw CImgInstanceException(_cimglist_instance\n                                        \"save_video(): Frame [0] is an empty image.\",\n                                        cimglist_instance);","sourceCodeStart":68550,"sourceCodeEnd":68586,"githubUrl":"https://github.com/Yalantis/uCrop/blob/f788b534b48c144edf786c8cddbf0e029e637804/ucrop/src/main/jni/CImg.h#L68550-L68586","documentation":"save_video() supports resuming writes to an already-open cv::VideoWriter by passing a null filename on subsequent calls. This argument exception is thrown when the first call (or a call after all slots were closed) passes a null filename, so there is no open writer to reuse.","triggerScenarios":"Calling list.save_video((const char*)0, ...) or save_video(nullptr) with no video writer previously opened for this list; the internal index lookup returns -1 and filename is null.","commonSituations":"Reusing save_video code paths across lists without keeping the filename argument on the first call; mismanaged writer lifecycle where close_save_video() was already called.","solutions":["Pass a valid non-null output filename (e.g. 'out.avi') on the first save_video() call for the list","Track whether a writer is already open before passing null","Re-open a writer with a filename after any close_save_video()","Refactor to keep one persistent list instance for the whole video-writing session"],"exampleFix":"// before\nframes.save_video(nullptr); // first call, no open writer\n// after\nframes.save_video(\"output.avi\", 25, \"h264\"); // first call needs filename","handlingStrategy":"validation","validationCode":"// C++\nbool firstCall = !writerOpen;\nif (firstCall && (filename == nullptr || filename[0] == '\\0')) return fail(\"filename required for first save_video call\");","typeGuard":"bool hasFilename(const char* f) { return f != nullptr && f[0] != '\\0'; }","tryCatchPattern":"try { frames.save_video(fname, fps, codec); }\ncatch (CImgArgumentException& e) { fprintf(stderr, \"need filename on first call: %s\", e.what()); }","preventionTips":["Always pass a filename on the first save_video() for a list","Keep one list instance per video session","Never call close_save_video() then continue passing null","Wrap video writes in a small class that tracks open state"],"tags":["video","arguments","null-argument","opencv"],"backgroundTag":"missing-required-argument","analyzedSha":"f788b534b48c144edf786c8cddbf0e029e637804","analyzedAt":"2026-09-08T08:36:04.887Z","contentChangedAt":"2026-09-08T08:36:04.887Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}