JetBrains/intellij-community · error · PrepareFailedException

Unable to extract method from annotation value

Error message

Unable to extract method from annotation value

What it means

ExtractMethodProcessor passes over the selected elements and, if any lies inside a PsiAnnotation (PsiTreeUtil.getParentOfType finds an annotation ancestor, following the code-fragment member for non-physical elements), throws PrepareFailedException with 'extract.method.error.annotation.value'. Java annotation member values are highly constrained (constant expressions only), so extracting them into a method is not representable and the refactoring refuses to run.

Source

Thrown at java/java-impl-refactorings/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java:374

      }
      else {
        myExpression = expression;
      }
    }

    final PsiElement codeFragment = ControlFlowUtil.findCodeFragment(myElements[0]);
    myCodeFragmentMember = codeFragment.getUserData(ElementToWorkOn.PARENT);
    if (myCodeFragmentMember == null) {
      myCodeFragmentMember = codeFragment.getParent();
    }
    if (myCodeFragmentMember == null) {
      PsiElement context = codeFragment.getContext();
      LOG.assertTrue(context != null, "code fragment context is null: " + codeFragment.getClass());
      myCodeFragmentMember = ControlFlowUtil.findCodeFragment(context).getParent();
    }

    if (PsiTreeUtil.getParentOfType(myElements[0].isPhysical() ? myElements[0] : myCodeFragmentMember, PsiAnnotation.class) != null) {
      throw new PrepareFailedException(JavaRefactoringBundle.message("extract.method.error.annotation.value"), myElements[0]);
    }

    myControlFlowWrapper = new ControlFlowWrapper(codeFragment, myElements);

    try {
      myExitStatements = myControlFlowWrapper.prepareAndCheckExitStatements(myElements, codeFragment);
      if (myControlFlowWrapper.isGenerateConditionalExit()) {
        myGenerateConditionalExit = true;
      } else {
        myHasReturnStatement = myExpression == null && myControlFlowWrapper.isReturnPresentBetween();
      }
      myFirstExitStatementCopy = myControlFlowWrapper.getFirstExitStatementCopy();
    }
    catch (ControlFlowWrapper.ExitStatementsNotSameException e) {
      myExitStatements = myControlFlowWrapper.getExitStatements();
      myNotNullConditionalCheck = areAllExitPointsNotNull(getExpectedReturnType());
      if (!myNotNullConditionalCheck) {
        showMultipleExitPointsMessage();

View on GitHub (pinned to be881553f2)

Solutions

  1. Cancel the refactoring — annotation values cannot be replaced by method calls by language rules.
  2. Extract the shared constant into a static final constant instead, then reference that constant from the annotation (constants are allowed in annotation values).
  3. If the annotation is your own, consider a repeatable/alias annotation or a constant defined next to it.
  4. Make sure the selection is really the code you think: caret inside a normal method body, not an annotation argument.

Example fix

// before:
@SuppressWarnings({"unused", "rawtypes"})
class A { }
// selecting "unused" inside the annotation and pressing Extract Method fails

// after:
class A {
  static final String[] SUPPRESS = {"unused", "rawtypes"};
  @SuppressWarnings(SUPPRESS)
  static class B { }
}
Defensive patterns

Strategy: validation

Validate before calling

PsiElement anchor = elements[0].isPhysical() ? elements[0] : codeFragmentMember;
if (PsiTreeUtil.getParentOfType(anchor, PsiAnnotation.class) != null) {
  // selection lives inside an annotation value: block Extract Method with an explanation
}

Try / catch

try { processor.prepare(); } catch (PrepareFailedException e) { /* show message and element; extraction inside annotation values is impossible */ }

Prevention

When it happens

Trigger: Selecting an expression inside an annotation value — e.g. part of the 'value = ...' argument of @SuppressWarnings("...") or an array initializer inside @MyAnnotation({...}) — and invoking Extract Method.

Common situations: Users trying to deduplicate constant expressions used in annotations; selecting inside generated or injected code hosted in annotation values; refactorings invoked on fragments whose code-fragment member resolves into an annotation (including non-physical copies in editor previews).

Related errors


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