JetBrains/intellij-community · error · EvaluateException

inconvertible.type.cast

inconvertible.type.cast

Error message

Inconvertible types; cannot cast ''{0}'' to ''{1}''

What it means

Thrown at evaluator-build time when a cast expression in the evaluated fragment is provably invalid: the operand's resolved PSI type and the target cast type are not convertible per TypeConversionUtil and the operand class resolves. This mirrors the Java compiler's inconvertible-types error, catching it before the code ever runs in the debuggee.

Source

Thrown at java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java:1512

    public void visitTypeCastExpression(@NotNull PsiTypeCastExpression expression) {
      PsiExpression operandExpr = expression.getOperand();
      if (operandExpr == null) {
        throw expressionInvalid(expression);
      }
      operandExpr.accept(this);
      Evaluator operandEvaluator = myResult;
      PsiTypeElement castTypeElem = expression.getCastType();
      if (castTypeElem == null) {
        throw expressionInvalid(expression);
      }
      PsiType castType = castTypeElem.getType();
      PsiType operandType = operandExpr.getType();

      // if operand type can not be resolved in current context - leave it for runtime checks
      if (operandType != null &&
          !TypeConversionUtil.areTypesConvertible(operandType, castType) &&
          PsiUtil.resolveClassInType(operandType) != null) {
        throw new EvaluateRuntimeException(
          new EvaluateException(
            JavaErrorBundle.message("inconvertible.type.cast", JavaHighlightUtil.formatType(operandType), JavaHighlightUtil
              .formatType(castType)))
        );
      }

      boolean shouldPerformBoxingConversion = operandType != null && TypeConversionUtil.boxingConversionApplicable(castType, operandType);
      final boolean castingToPrimitive = castType instanceof PsiPrimitiveType;
      if (shouldPerformBoxingConversion && castingToPrimitive) {
        operandEvaluator = new UnBoxingEvaluator(operandEvaluator);
      }

      final boolean performCastToWrapperClass = shouldPerformBoxingConversion && !castingToPrimitive;

      if (!(PsiUtil.resolveClassInClassTypeOnly(castType) instanceof PsiTypeParameter)) {
        if (performCastToWrapperClass) {
          castType = ObjectUtils.notNull(PsiPrimitiveType.getUnboxedType(castType), operandType);
        }

View on GitHub (pinned to be881553f2)

Solutions

  1. Fix the cast to a type the operand can actually convert to (e.g. Integer.parseInt(str) instead of (int) str)
  2. Cast through an intermediate type: first (Object) then the target, when you know better than the static types
  3. Re-resolve: if the code changed since compile, rebuild the project so PSI types match the running classes

Example fix

// before: (int) someString

// after: Integer.parseInt(someString)
// or when certain: (int)(Object) boxedInteger
Defensive patterns

Strategy: type-guard

Validate before calling

PsiType operandType = operandExpr.getType();
if (operandType != null && PsiUtil.resolveClassInType(operandType) != null
    && !TypeConversionUtil.areTypesConvertible(operandType, castType)) {
  // reject before evaluating, or go through (Object)
}

Type guard

static boolean castIsSafe(@Nullable PsiType from, PsiType to) {
  return from == null || PsiUtil.resolveClassInType(from) == null
      || TypeConversionUtil.areTypesConvertible(from, to);
}

Try / catch

try {
  result = evaluator.evaluate(context);
} catch (EvaluateRuntimeException e) {
  if (e.getCause() instanceof EvaluateException && /* inconvertible cast */) {
    // suggest (Object) intermediate cast to the user
  }
}

Prevention

When it happens

Trigger: Visiting a PsiTypeCastExpression where operandType != null, PsiUtil.resolveClassInType(operandType) != null, and TypeConversionUtil.areTypesConvertible(operandType, castType) is false; e.g. casting a String literal to int, or an Integer to List. Boxing casts to primitives are handled separately after this check.

Common situations: User writes '(int) str' or '(List<String>) integerValue' in the Evaluate dialog; generics erasure edge cases where the static evaluator type is an unrelated class; refactoring changed the operand type since the breakpoint was hit.

Related errors


AI-assisted analysis of JetBrains/intellij-community@be881553f2 (2026-08-14). Data as JSON: /api/errors/350bee371cb4ff7f. Report an issue: GitHub.