{"record":{"id":"2040c8a083fd7bb8","repo":"JetBrains/intellij-community","slug":"cannot-extract-method-because-the-selected-code-fr-2040c8","errorCode":null,"errorMessage":"Cannot extract method because the selected code fragment defines local classes used outside of the fragment","messagePattern":"Cannot extract method because the selected code fragment defines local classes used outside of the fragment","errorType":"exception","errorClass":"PrepareFailedException","httpStatus":null,"severity":"error","filePath":"java/java-impl-refactorings/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java","lineNumber":683,"sourceCode":"      final List<PsiElement> remainingReferences = Collections.synchronizedList(new ArrayList<>());\n      ReferencesSearch.search(localClass).forEach(psiReference -> {\n        final PsiElement element = psiReference.getElement();\n        final boolean elementExtracted = isExtractedElement(element);\n        if (elementExtracted && !classExtracted) {\n          extractedReferences.add(element);\n          return false;\n        }\n        if (!elementExtracted && classExtracted) {\n          remainingReferences.add(element);\n          return false;\n        }\n        return true;\n      });\n      if (!extractedReferences.isEmpty()) {\n        throw new PrepareFailedException(JavaRefactoringBundle.message(\"extract.method.error.local.class.defined.outside\"), extractedReferences.get(0));\n      }\n      if (!remainingReferences.isEmpty()) {\n        throw new PrepareFailedException(JavaRefactoringBundle.message(\"extract.method.error.local.class.used.outside\"), remainingReferences.get(0));\n      }\n      if (classExtracted) {\n        for (PsiVariable variable : myControlFlowWrapper.getUsedVariables()) {\n          if (isDeclaredInside(variable) && !variable.equals(myOutputVariable) && PsiUtil.resolveClassInType(variable.getType()) == localClass) {\n            throw new PrepareFailedException(JavaRefactoringBundle.message(\"extract.method.error.local.class.variable.used.outside\"), variable);\n          }\n        }\n      }\n    }\n  }\n\n  private boolean isExtractedElement(final PsiElement element) {\n    boolean isExtracted = false;\n    for(PsiElement psiElement: myElements) {\n      if (PsiTreeUtil.isAncestor(psiElement, element, false)) {\n        isExtracted = true;\n        break;\n      }","sourceCodeStart":665,"sourceCodeEnd":701,"githubUrl":"https://github.com/JetBrains/intellij-community/blob/be881553f2a76ac8b4ea53950d93f0de78295c19/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java#L665-L701","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before:\nvoid m() {\n  // selection: class Local { void go() {} }\n  // ... extraction fails because the line below stays outside\n  new Local().go();\n}\n\n// after (hoist):\nclass Owner {\n  private static class Local { void go() {} }\n  void m() {\n    // extracted fragment can now use Owner.Local\n    new Local().go();\n  }\n}","handlingStrategy":"validation","validationCode":"for (PsiClass local : classesDeclaredInsideSelection) {\n  if (isReferencedFromOutside(local, elements)) {\n    // widen selection, or hoist the local class to a nested class before extracting\n  }\n}","typeGuard":null,"tryCatchPattern":"try { processor.prepare(); } catch (PrepareFailedException e) { /* first remaining reference is provided; use it to extend selection */ }","preventionTips":["Extract fragments that are self-contained with respect to local classes.","Convert local classes used across the method into private nested classes first."],"tags":["java","intellij","refactoring","extract-method","local-class","scoping"],"backgroundTag":null,"analyzedSha":"be881553f2a76ac8b4ea53950d93f0de78295c19","analyzedAt":"2026-08-14T14:13:06.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}