Yalantis/uCrop · error · CImgArgumentException

save_imagemagick_external(): Specified filename is (null).

Error message

save_imagemagick_external(): Specified filename is (null).

What it means

CImg::save_imagemagick_external() validates its arguments before doing any work. Passing a NULL filename pointer is a programming error, so CImg throws CImgArgumentException immediately. No file system or external command is involved.

Solutions

  1. Check the filename pointer for NULL before calling save_imagemagick_external().
  2. Fix the upstream code that produced a NULL path (failed allocation, missing config, failed lookup).
  3. Provide a default output path when the computed one is unavailable.
  4. Use std::string and pass .c_str() only after confirming non-empty content.

Example fix

// before
const char* path = getenv("OUT");
img.save_imagemagick_external(path); // path may be NULL
// after
const char* path = getenv("OUT");
if (path) img.save_imagemagick_external(path);
else img.save_imagemagick_external("default.jpg");
Defensive patterns

Strategy: type-guard

Validate before calling

if (!filename || !*filename) { /* use default or error out before calling */ }

Type guard

bool validPath(const char* p) { return p != nullptr && *p != '\0'; }

Try / catch

try {
  img.save_imagemagick_external(filename);
} catch (CImgArgumentException& e) {
  std::fprintf(stderr, "bad filename: %s", e.what());
}

Prevention

When it happens

Trigger: Calling save_imagemagick_external(nullptr) or passing a char* variable that was never initialized / was set to NULL by a failed lookup (e.g. result of a function returning NULL on error).

Common situations: Constructing the filename dynamically and failing to check for NULL before the save call; using a path returned from an environment/config lookup that returned null.

Related errors


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

Appendix: source

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

                              "save_graphicsmagick_external(): Failed to save file '%s' with external command 'gm'.",
                              cimg_instance,
                              filename);

      std::remove(filename_tmp);
      return *this;
    }

    //! Save image using ImageMagick's external binary.
    /**
       \param filename Filename, as a C-string.
       \param quality Image quality (expressed in percent), when the file format supports it.
       \note This method uses \c convert, an external executable binary provided by
       <a href="http://www.imagemagick.org">ImageMagick</a>.
       It must be installed for the method to succeed.
    **/
    const CImg<T>& save_imagemagick_external(const char *const filename, const unsigned int quality=100) const {
      if (!filename)
        throw CImgArgumentException(_cimg_instance
                                    "save_imagemagick_external(): Specified filename is (null).",
                                    cimg_instance);
      if (is_empty()) { cimg::fempty(0,filename); return *this; }
      if (_depth>1)
        cimg::warn(_cimg_instance
                   "save_other(): File '%s', saving a volumetric image with an external call to "
                   "ImageMagick only writes the first image slice.",
                   cimg_instance,filename);
#ifdef cimg_use_png
#define _cimg_sie_extension1 "png"
#define _cimg_sie_extension2 "png"
#else
#define _cimg_sie_extension1 "pgm"
#define _cimg_sie_extension2 "ppm"
#endif
      CImg<charT> command(1024), filename_tmp(256);
      do {
        cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s.%s",cimg::temporary_path(),

View on GitHub (pinned to f788b534b4)