Yalantis/uCrop · error · CImgArgumentException

[" cimg_appname "_math_parser] CImg<

Error message

[" cimg_appname "_math_parser] CImg<%s>::%s: %s: Invalid specified operator (should be one of '=,+,-,*,/,&,|,xor,&&,||,min,max'), in expression '%s'.

What it means

Math parser error raised while compiling an assignment/merge operation (e.g. in memmerge handling): the operator string between operands did not match any of the accepted tokens '=,+,-,*,/,&,|,xor,&&,||,min,max', so the variable merge instruction cannot be generated.

Solutions

  1. Use one of the supported operators: =,+,-,*,/,&,|,xor,&&,||,min,max
  2. Implement 'avg' manually as sum/count using '+' then divide after merge
  3. Fix typos in the operator argument (e.g. 'min' not 'minimum')

Example fix

// before
merge(V,0,avg)
// after
merge(V,0,+); V/=N
Defensive patterns

Strategy: validation

Validate before calling

const ops = ['=','+','-','*','/','&','|','xor','&&','||','min','max'];
ops.includes(op) || error('unsupported merge operator: ' + op);

Try / catch

try { run(expr) } catch (CImgArgumentException &e) { log(e.what()); }

Prevention

When it happens

Trigger: Passing an unsupported or misspelled operator string to merge(), e.g. 'merge(V,0,mod)', 'merge(V,0,avg)', or an empty/garbled operator token.

Common situations: Assuming merge supports arbitrary operators (mean, pow, %), typos in custom commands, or translating scripts from other mini-languages with richer operator sets.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

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

                    else if (*st_op=='&' && st_op[1]=='&' && !st_op[2]) arg1 = 8;
                    else if (*st_op=='|' && st_op[1]=='|' && !st_op[2]) arg1 = 9;
                    else if (*st_op=='m' && st_op[1]=='i' && st_op[2]=='n' && !st_op[3]) arg1 = 10;
                    else if (*st_op=='m' && st_op[1]=='a' && st_op[2]=='x' && !st_op[3]) arg1 = 11;
                  }
                }
              }

              cimg_rofY(memmerge,k) if (memmerge(0,k)==(int)pos) {
                _cimg_mp_strerr;
                throw CImgArgumentException("[" cimg_appname "_math_parser] "
                                            "CImg<%s>::%s: %s: Merge has already been requested before "
                                            "for specified variable "
                                            "in expression '%s'.",
                                            pixel_type(),_cimg_mp_calling_function,s_op,s0);
              }
              if (arg1==~0U) {
                _cimg_mp_strerr;
                throw CImgArgumentException("[" cimg_appname "_math_parser] "
                                            "CImg<%s>::%s: %s: Invalid specified operator "
                                            "(should be one of '=,+,-,*,/,&,|,xor,&&,||,min,max'), "
                                            "in expression '%s'.",
                                            pixel_type(),_cimg_mp_calling_function,s_op,s0);
              }
              memmerge.resize(3,memmerge._height + 1,1,1,0,0);
              memmerge(0,memmerge._height - 1) = (int)pos;
              memmerge(1,memmerge._height - 1) = (int)size(pos);
              memmerge(2,memmerge._height - 1) = (int)arg1;
              _cimg_mp_return_nan();
            }
            break;

          case 'n' :
#ifdef cimg_mp_func_name
            if (!std::strncmp(ss,"name(",5)) { // Get image name as a string vector
              _cimg_mp_op("Function 'name()'");
              if (*ss5=='#') { // Index specified

View on GitHub (pinned to f788b534b4)