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 variable of local class type used outside of the fragment
What it means
PrepareFailedException thrown by ExtractMethodProcessor when a local class is extracted along with the fragment, and a variable declared inside the fragment (and not the output variable) has that local class as its type. Such a variable cannot survive extraction: the new method would have to return it, but the local class type would then leak to callers that cannot name it, so the prepare step rejects the extraction, pointing at the offending variable.
Source
Thrown at java/java-impl-refactorings/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java:688
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;
}
}
return isExtracted;
}
View on GitHub (pinned to be881553f2)
Solutions
- Promote the local class to a private nested or top-level class first; then the variable's type is nameable and extraction can proceed.
- Keep the variable inside the extracted fragment by restructuring so it is not used after the fragment (or return an interface/supertype instead).
- Include the later usages in the selection so the variable does not cross the boundary.
- Replace the local class with an existing interface type for the variable declaration where feasible.
Example fix
// before:
void m() {
// selection:
class L { int v; }
L state = new L();
// ... 'state' used after fragment -> fails
}
// after:
class Owner {
private static class L { int v; }
void m() {
L state = new L(); // extraction of the body now possible
}
} Defensive patterns
Strategy: validation
Validate before calling
for (PsiVariable var : controlFlowWrapper.getUsedVariables()) {
if (isDeclaredInside(var) && !var.equals(outputVariable)
&& PsiUtil.resolveClassInType(var.getType()) == extractedLocalClass) {
// variable of local class type crosses the boundary: hoist the class or restructure
}
} Try / catch
try { processor.prepare(); } catch (PrepareFailedException e) { /* failing variable is attached; promote the local class to nested first */ } Prevention
- Promote local classes to nested/top-level classes before extracting fragments that expose them.
- Keep variables of local class types entirely inside or entirely outside the extracted fragment.
When it happens
Trigger: Extracting a fragment that declares 'class L {}' plus 'L var = new L();' where 'var' is used after the fragment (it appears in getUsedVariables), i.e. it would need to become an output of the extracted method with an unnameable type.
Common situations: Extracting builder/state-holder blocks built around a local class; selections that declare a local class and assign instances to variables consumed later in the method; refactoring helper classes introduced during stepwise extraction.
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/402b3a53abb76c23.
Report an issue: GitHub.