Yalantis/uCrop · error · CImgArgumentException

[cimg_appname_math_parser] CImg<

Error message

[cimg_appname_math_parser] CImg<%s>::%s: %s: %s arguments, in expression '%s'.

What it means

The expression parser encountered a construct that requires between 1 and 10 arguments, but found 0 ("Missing") or more than 10 ("Too much") after parsing the comma-separated argument list. This guards opcode argument lists whose argument count is bounded at compile time.

Solutions

  1. Count the arguments between the parentheses; supply at least 1 and at most 10.
  2. Remove stray/empty arguments caused by trailing commas (e.g. 'f(a,b,)').
  3. If more than 10 inputs are needed, split into intermediate named variables or nested calls.

Example fix

// before
'op()'
// after
'op(0)'
Defensive patterns

Strategy: validation

Validate before calling

const args = inner.split(',').filter(a => a.trim() !== '');
if (args.length < 1 || args.length > 10) throw new Error('Argument count ' + args.length + ' out of range 1..10');

Try / catch

try { img.eval(expr); } catch (e) { if (/arguments, in expression/.test(e.message)) { /* inspect arg list */ } else throw e; }

Prevention

When it happens

Trigger: Writing an empty argument list 'op()' for a construct needing at least one argument, or passing more than 10 comma-separated arguments to a parser opcode with a fixed argument register limit.

Common situations: Trailing commas creating an empty argument, editing an expression and deleting the only argument, or programmatically generated argument lists overflowing the 10-argument cap.

Related errors


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

Appendix: source

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

                s0 = ss8; while (s0<se1 && (*s0!=',' || level[s0 - expr._data]!=clevel1)) ++s0;
                p1 = compile(ss8,s0++,depth1,0,block_flags);
                _cimg_mp_check_list();
                l_opcode.assign(); // Don't use 'opcode': it can be modified by further calls to 'compile()'!
                CImg<ulongT>::vector((ulongT)mp_image_resize,_cimg_mp_slot_nan,p1,~0U,~0U,~0U,~0U,1,0,0,0,0,0).
                  move_to(l_opcode);
                pos = 0;
                for (s = s0; s<se && pos<10; ++s) {
                  ns = s; while (ns<se && (*ns!=',' || level[ns - expr._data]!=clevel1) &&
                                 (*ns!=')' || level[ns - expr._data]!=clevel)) ++ns;
                  arg1 = compile(s,ns,depth1,0,block_flags);
                  _cimg_mp_check_type(arg1,pos + 2,1,0);
                  l_opcode(0,pos + 3) = arg1;
                  s = ns;
                  ++pos;
                }
                if (pos<1 || pos>10) {
                  _cimg_mp_strerr;
                  throw CImgArgumentException("[" cimg_appname "_math_parser] "
                                              "CImg<%s>::%s: %s: %s arguments, in expression '%s'.",
                                              pixel_type(),_cimg_mp_calling_function,s_op,
                                              pos<1?"Missing":"Too much",s0);
                }
                l_opcode[0].move_to(code);
                _cimg_mp_return_nan();
              }
            }

            if (!std::strncmp(ss,"reverse(",8)) { // Vector reverse
              _cimg_mp_op("Function 'reverse()'");
              arg1 = compile(ss8,se1,depth1,0,block_flags);
              if (!is_vector(arg1)) _cimg_mp_same(arg1);
              p1 = size(arg1);
              pos = vector(p1);
              CImg<ulongT>::vector((ulongT)mp_reverse,pos,arg1,p1).move_to(code);
              return_comp = true;
              _cimg_mp_return(pos);

View on GitHub (pinned to f788b534b4)