Yalantis/uCrop · error · CImgArgumentException

[cimg_appname_math_parser] CImg<

Error message

[cimg_appname_math_parser] CImg<%s>::%s: %s: %s argument cannot be a constant, in expression '%s'.

What it means

The swap-style opcode exchanges the contents of its two operands, so both must be writable (mutable, non-constant) slots in the parser's memory. If either compiled argument is a constant scalar/vector, compilation fails naming which one (First or Second) is constant.

Solutions

  1. Ensure both arguments are named variables/vectors declared with scalar()/vector(name) and assigned at runtime.
  2. Replace literals with variables initialized to the literal value before swapping.
  3. Check that you did not accidentally pass a pre-defined constant as one operand.

Example fix

// before
'swap(1,x)'
// after
'a=1; swap(a,x)'
Defensive patterns

Strategy: type-guard

Validate before calling

// both operands must be declared, mutable variables
if (!declaredVars.has(a) || !declaredVars.has(b)) throw new Error('swap operands must be mutable variables');

Type guard

const isMutableVar = (tok) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(tok) && declaredVars.has(tok) && !constNames.has(tok);

Try / catch

try { img.eval(expr); } catch (e) { if (/argument cannot be a constant/.test(e.message)) { /* replace literal operand with a variable */ } else throw e; }

Prevention

When it happens

Trigger: Calling swap(a,b) where a or b is a literal (e.g. swap(1,x)), a const vector, or an expression result rather than a named variable/vector slot.

Common situations: Trying to swap into a constant; passing literals by accident; shadowing a variable with a constant; misunderstanding that swap mutates in place and requires lvalues.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

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

                _cimg_mp_check_notnan_index(p1,ss6);
                _cimg_mp_check_list();
                s1 = s0; while (s1<se1 && (*s1!=',' || level[s1 - expr._data]!=clevel1)) ++s1; // pos0
                arg1 = compile(s0,s1,depth1,0,block_flags);
                s2 = ++s1; while (s2<se1 && (*s2!=',' || level[s2 - expr._data]!=clevel1)) ++s2; // pos1
                arg2 = compile(s1,s2,depth1,0,block_flags);
                arg3 = s2<se1?compile(++s2,se1,depth1,0,block_flags):0; // is_vector?
                CImg<ulongT>::vector((ulongT)mp_image_swap,_cimg_mp_slot_nan,p1,arg1,arg2,arg3).move_to(code);

              } else {
                s1 = ss5; while (s1<se1 && (*s1!=',' || level[s1 - expr._data]!=clevel1)) ++s1;
                ref.assign(14);
                arg1 = compile(ss5,s1,depth1,ref,block_flags);
                arg2 = compile(++s1,se1,depth1,ref._data + 7,block_flags);
                p1 = size(arg1);
                _cimg_mp_check_type(arg2,2,p1?2:1,p1);
                if (is_const_scalar(arg1) || is_const_scalar(arg2)) {
                  _cimg_mp_strerr;
                  throw CImgArgumentException("[" cimg_appname "_math_parser] "
                                              "CImg<%s>::%s: %s: %s argument cannot be a constant, "
                                              "in expression '%s'.",
                                              pixel_type(),_cimg_mp_calling_function,s_op,
                                              is_const_scalar(arg1)?"First":"Second",s0);
                }
                CImg<ulongT>::vector((ulongT)mp_swap,arg1,arg2,p1).move_to(code);

                // Write back values of linked arg1 and arg2.
                const unsigned int *_ref = ref;
                is_sth = true; // Is first argument?
                do {
                  switch (*_ref) {
                  case 1 : // arg1: V[k]
                    arg3 = _ref[1]; // Vector slot
                    arg4 = _ref[2]; // Index
                    CImg<ulongT>::vector((ulongT)mp_vector_set_off,arg1,arg3,(ulongT)size(arg3),arg4).
                      move_to(code);
                    break;

View on GitHub (pinned to f788b534b4)