Yalantis/uCrop · error · CImgArgumentException

[cimg_appname_math_parser] CImg<%s>::%s: %s: Invalid types i

Error message

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

What it means

A type-validation failure in the vector-drawing branch of a drawing opcode (the branch handling drawing into a vector with the 17-slot layout: coords, color, opacity, mask M, maxM). After generating code for the accepted argument types, the parser's final `else` fires when the supplied arguments don't match any supported type combination — e.g. a coordinate argument that is neither a scalar nor a proper vector. It reports 'Invalid types in specified arguments' rather than a count problem.

Source

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

                  _cimg_mp_check_type((unsigned int)opcode[10],11,1,0); // dx
                  _cimg_mp_check_type((unsigned int)opcode[11],12,1,0); // dy
                  _cimg_mp_check_type((unsigned int)opcode[12],13,1,0); // dz
                  _cimg_mp_check_type((unsigned int)opcode[13],14,1,0); // dc
                  if (opcode._height>14) _cimg_mp_check_type((unsigned int)opcode[14],15,1,0); // opac
                  if (opcode._height>16) _cimg_mp_check_type((unsigned int)opcode[16],17,1,0); // maxM
                  CImg<ulongT>::vector((ulongT)mp_vector_draw,
                                       *opcode,size((unsigned int)*opcode), // 1-2: D,sizD
                                       opcode[1],opcode[2],opcode[3],opcode[4], // 3-6: w,h,d,s
                                       opcode[5],size((unsigned int)opcode[5]), // 7-8: S,sizS
                                       opcode[6],opcode[7],opcode[8],opcode[9], // 9-12: x,y,z,c
                                       opcode[10],opcode[11],opcode[12],opcode[13], // 13-16: dx,dy,dz,dc
                                       opcode._height<15?1:opcode[14], // 17: opac
                                       opcode._height<16?~0U:opcode[15], // 18: M
                                       opcode._height<16?0:size((unsigned int)opcode[15]), // 19: sizM
                                       opcode._height<17?1:opcode[16]).move_to(code); // 20: maxM
                } else {
                  _cimg_mp_strerr;
                  throw CImgArgumentException("[" cimg_appname "_math_parser] "
                                              "CImg<%s>::%s: %s: Invalid types in specified arguments, "
                                              "in expression '%s'.",
                                              pixel_type(),_cimg_mp_calling_function,s_op,s0);
                }

              } else { // Drawing in an image
                if (!is_inside_critical) is_parallelizable = false;
                arg1 = p1!=~0U;
                _cimg_mp_check_type((unsigned int)*opcode,1 + arg1,2,0); // S
                if (opcode._height<3 || (opcode._height<5 && is_vector((unsigned int)opcode[2]))) {
                  // S[,opac,M,maxM].
                  if (opcode._height>1) _cimg_mp_check_type((unsigned int)opcode[1],2 + arg1,1,0); // opac
                  if (opcode._height>3) _cimg_mp_check_type((unsigned int)opcode[3],4 + arg1,1,0); // maxM
                  CImg<ulongT>::vector((ulongT)mp_image_draw,
                                       *opcode,size((unsigned int)*opcode),p1, // 1-3: S,sizS,#ind
                                       0,0,0,0, // 4-7: x,y,z,c
                                       ~0U,~0U,~0U,~0U, // 8-11: dx,dy,dz,dc
                                       opcode._height<2?1:opcode[1], // 12: opac

View on GitHub (pinned to f788b534b4)

Solutions

  1. Ensure each argument has the type the slot expects: scalars for coordinates/opacity, vectors for color and mask M.
  2. Check the arguments positionally against the 17-slot layout (coords..., color vector, opac, M, maxM).
  3. Use `_cimg_mp`-documented type checks mentally: is_vector()/is_scalar() on the failing argument.
  4. Split the call and assign intermediate named variables so types are explicit.

Example fix

// before
draw(V, x, y, 255) // scalar where color vector expected -> invalid types
// after
color = [255,255,255]; draw(V, x, y, color, 255);
Defensive patterns

Strategy: type-guard

Validate before calling

// verify vector-typed slots before evaluating
if (!color.is_vector()) throw std::runtime_error("color argument must be a vector");
if (!std::isfinite(opac)) throw std::runtime_error("opacity must be a scalar");

Type guard

bool args_well_typed(const CImg<float>& color, float opac, const CImg<float>* mask) {
  return color.is_vector() && std::isfinite(opac) && (!mask || mask->is_vector());
}

Try / catch

try {
  img.fill(expr.c_str());
} catch (const CImgArgumentException& e) {
  // invalid draw argument types: log expression and skip drawing
}

Prevention

When it happens

Trigger: Calling the vector draw function where required arguments have wrong expression types: e.g. passing a non-vector where a color/mask vector is expected, a vector where a scalar coordinate is required, or omitting arguments in a way that makes positionally-read types wrong (color read as coordinate, etc.).

Common situations: Swapping two arguments (opacity before color); passing an image variable where a vector variable is expected; relying on defaults but with the wrong types in early positions shifting everything; expressions ported from the image-draw variant.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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