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
- Cancel the refactoring — annotation values cannot be replaced by method calls by language rules.
- Extract the shared constant into a static final constant instead, then reference that constant from the annotation (constants are allowed in annotation values).
- If the annotation is your own, consider a repeatable/alias annotation or a constant defined next to it.
- 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
- Never attempt to extract code inside annotation arguments; hoist the value into a constant instead.
- Check the selection is in a method body (not an annotation) before offering the action.
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
- Cannot extract method because the selected code fragment use
- Cannot extract method because the selected code fragment def
- Cannot extract method because the selected code fragment def
- extract.method.control.flow.analysis.failed
- Cannot create package '{0}' in source folder {1}
AI-assisted analysis of JetBrains/intellij-community@be881553f2 (2026-08-14).
Data as JSON: /api/errors/1a0cf8c1c20656d4.
Report an issue: GitHub.