Yalantis/uCrop · error · CImgArgumentException

[" cimg_appname "_math_parser] CImg<

Error message

[" cimg_appname "_math_parser] CImg<%s>::%s: %s: Merge has already been requested before for specified variable in expression '%s'.

What it means

The math parser tracks requested merges per variable in the memmerge table. If the same variable position appears more than once as a merge target, the parser throws because two merge requests on one variable are ambiguous and unsupported within a single expression.

Solutions

  1. Use a distinct target variable for each merge operation
  2. Combine the merges into one call if the operator is the same
  3. Restructure the expression so the variable is merged once (e.g. accumulate into a temporary then assign)
  4. Split the computation into multiple expressions/runs if two merges are truly needed

Example fix

// before
merge(V,0,+); merge(V,0,min)
// after
merge(V,0,+); W = 0; merge(W,0,min)
Defensive patterns

Strategy: validation

Validate before calling

// track merge targets per expression; each variable may appear once
merged_vars = [] # assert V not already merged in this expression

Try / catch

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

Prevention

When it happens

Trigger: Calling merge() twice (or having two merge ops) on the same variable within one expression, e.g. 'merge(V,0,+); merge(V,1,min)'.

Common situations: Copy-pasting merge lines in a custom command, or a loop unrolled in an expression that repeatedly merges into the same accumulator variable.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

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

                if (cimg_sscanf(s1," %3[=+-*/&|minaxor]%c",st_op,&sep)==2 && (sep==')' ||
                                                                              (is_sth=cimg::is_blank(sep)))) {
                  if (!is_sth || (is_sth && cimg_sscanf(s1," %*[=+-*/&|minaxor ]%c",&sep)==1 && sep==')')) {
                    cimg::strpare(st_op,' ',false,true);
                    if (!st_op[1])
                      arg1 = *st_op=='='?0:*st_op=='+'?1:*st_op=='-'?2:*st_op=='*'?3:*st_op=='/'?4:
                        *st_op=='&'?5:*st_op=='|'?6:~0U;
                    else if (*st_op=='x' && st_op[1]=='o' && st_op[2]=='r' && !st_op[3]) arg1 = 7;
                    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();

View on GitHub (pinned to f788b534b4)