JetBrains/intellij-community · error · PrepareFailedException
Cannot extract method because the selected code fragment def
Error message
Cannot extract method because the selected code fragment defines local classes used outside of the fragment
What it means
PrepareFailedException thrown by ExtractMethodProcessor when a local or anonymous class is declared inside the selected fragment but referenced from code that remains outside it (remainingReferences non-empty). After extraction the class would move into the new method, so the leftover code in the original method could no longer resolve those references; the refactoring aborts instead of producing broken code.
Source
Thrown at java/java-impl-refactorings/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java:683
final List<PsiElement> remainingReferences = Collections.synchronizedList(new ArrayList<>());
ReferencesSearch.search(localClass).forEach(psiReference -> {
final PsiElement element = psiReference.getElement();
final boolean elementExtracted = isExtractedElement(element);
if (elementExtracted && !classExtracted) {
extractedReferences.add(element);
return false;
}
if (!elementExtracted && classExtracted) {
remainingReferences.add(element);
return false;
}
return true;
});
if (!extractedReferences.isEmpty()) {
throw new PrepareFailedException(JavaRefactoringBundle.message("extract.method.error.local.class.defined.outside"), extractedReferences.get(0));
}
if (!remainingReferences.isEmpty()) {
throw new PrepareFailedException(JavaRefactoringBundle.message("extract.method.error.local.class.used.outside"), remainingReferences.get(0));
}
if (classExtracted) {
for (PsiVariable variable : myControlFlowWrapper.getUsedVariables()) {
if (isDeclaredInside(variable) && !variable.equals(myOutputVariable) && PsiUtil.resolveClassInType(variable.getType()) == localClass) {
throw new PrepareFailedException(JavaRefactoringBundle.message("extract.method.error.local.class.variable.used.outside"), variable);
}
}
}
}
}
private boolean isExtractedElement(final PsiElement element) {
boolean isExtracted = false;
for(PsiElement psiElement: myElements) {
if (PsiTreeUtil.isAncestor(psiElement, element, false)) {
isExtracted = true;
break;
}View on GitHub (pinned to be881553f2)
Solutions
- Extend the selection to cover the remaining usages of the local class as well.
- Hoist the local class out of the method into a private nested class, then extract the fragment (references now resolve via the class, not the local scope).
- Split the work: first inline or restructure the outside usages (e.g. store the instance in a variable returned or widened), then extract.
- Choose a smaller fragment that neither declares nor uses the local class.
Example fix
// before:
void m() {
// selection: class Local { void go() {} }
// ... extraction fails because the line below stays outside
new Local().go();
}
// after (hoist):
class Owner {
private static class Local { void go() {} }
void m() {
// extracted fragment can now use Owner.Local
new Local().go();
}
} Defensive patterns
Strategy: validation
Validate before calling
for (PsiClass local : classesDeclaredInsideSelection) {
if (isReferencedFromOutside(local, elements)) {
// widen selection, or hoist the local class to a nested class before extracting
}
} Try / catch
try { processor.prepare(); } catch (PrepareFailedException e) { /* first remaining reference is provided; use it to extend selection */ } Prevention
- Extract fragments that are self-contained with respect to local classes.
- Convert local classes used across the method into private nested classes first.
When it happens
Trigger: Selecting a range that contains 'class Local {...}' or 'new Runnable(){...}' while later statements in the same method (outside the selection) still use that class or its instances.
Common situations: Extracting the setup half of a method whose second half uses the created listener/local type; extracting a block that declares a local class used in a finally or later branch; automated extract-method suggestions that stop mid-method.
Related errors
- Cannot extract method because the selected code fragment use
- Cannot extract method because the selected code fragment def
- Unable to extract method from annotation value
- 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/2040c8a083fd7bb8.
Report an issue: GitHub.