JetBrains/intellij-community · error · IncorrectOperationException

Invalid operation

Error message

Invalid operation

What it means

The reference inside a PsiEnumConstantImpl (an enum constant's reference to its enum class) supports handleElementRename as a no-op returning the element, but bindToElement is meaningless — an enum constant is declared inline in its enum, so it cannot be re-pointed at another element. bindToElement therefore always throws IncorrectOperationException("Invalid operation").

Source

Thrown at java/java-psi-impl/src/com/intellij/psi/impl/source/PsiEnumConstantImpl.java:272

      }
      else {
        return TextRange.from(startOffsetInParent, nameIdentifier.getTextLength());
      }
    }

    @Override
    public boolean isSoft() {
      return false;
    }

    @Override
    public PsiElement handleElementRename(@NotNull String newElementName) throws IncorrectOperationException {
      return getElement();
    }

    @Override
    public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
      throw new IncorrectOperationException("Invalid operation");
    }

    @Override
    public void processVariants(@NotNull PsiScopeProcessor processor) {
    }

    @Override
    public JavaResolveResult @NotNull [] multiResolve(boolean incompleteCode) {
      JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject());
      PsiClass containingClass = getContainingClass();
      if (containingClass == null) return JavaResolveResult.EMPTY_ARRAY;
      PsiClassType type = facade.getElementFactory().createType(containingClass);
      return facade.getResolveHelper().multiResolveConstructor(type, getArgumentList(), getElement());
    }

    @Override
    public @NotNull JavaResolveResult advancedResolve(boolean incompleteCode) {
      JavaResolveResult[] results = multiResolve(incompleteCode);

View on GitHub (pinned to be881553f2)

Solutions

  1. Do not call bindToElement for references inside enum constants; treat handleElementRename (or plain text replacement) as the only supported mutation.
  2. Filter such references before binding: check ref.getElement().getParent() instanceof PsiEnumConstant or skip references whose resolve() is the enum class itself.
  3. If moving an enum constant, delete and re-create it in the target enum via PsiElementFactory instead of rebinding.

Example fix

// before
ref.bindToElement(newTarget); // ref belongs to an enum constant -> always throws

// after
if (ref.getElement().getParent() instanceof PsiEnumConstant) {
  // enum constants cannot be rebound; rename only
  ref.handleElementRename(newName);
} else {
  ref.bindToElement(newTarget);
}
Defensive patterns

Strategy: validation

Validate before calling

if (ref.getElement().getParent() instanceof PsiEnumConstant) return; // bind unsupported

Try / catch

try { ref.bindToElement(t); } catch (IncorrectOperationException e) { /* enum constant refs: rename only */ }

Prevention

When it happens

Trigger: Calling bindToElement on the reference of an enum constant (e.g. the reference returned by an enum constant's name identifier context, or ((PsiReferenceExpression)enumConstant).bindToElement(...) style generic code) with any target element.

Common situations: Generic refactoring pipelines that call bindToElement on every PsiReference after moving/renaming a target; 'safe delete'/move refactorings that try to rebind enum constant references to other classes.

Related errors


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