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
- Ensure both arguments are named variables/vectors declared with scalar()/vector(name) and assigned at runtime.
- Replace literals with variables initialized to the literal value before swapping.
- 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
- Never pass literals or constants to swap-like mutating opcodes.
- Initialize a variable to hold any literal you need to swap.
- Maintain a constness set in your expression builder.
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
- [" cimg_appname "_math_parser] CImg<
- "[" cimg_appname "_math_parser] CImg<
- [" cimg_appname "_math_parser] CImg<
- [" cimg_appname "_math_parser] CImg<
- "[" cimg_appname "_math_parser] CImg<
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)