JetBrains/intellij-community · error · IncorrectOperationException

Cannot set package name for module declarations

Error message

Cannot set package name for module declarations

What it means

PsiJavaFileBaseImpl.setPackageName rewrites the package statement of a Java file, but module-info.java describes a Java module, not a packaged compilation unit; its 'package' concept is fixed, so the method throws IncorrectOperationException("Cannot set package name for module declarations") when PsiUtil.isModuleFile(this) is true.

Source

Thrown at java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaFileBaseImpl.java:170

  public @NotNull String getPackageName() {
    return withGreenStubOrAst(
      PsiJavaFileStub.class,
      stub -> stub.getPackageName(),
      ast -> {
        String name = myPackageName;
        if (name == null) {
          PsiPackageStatement statement = getPackageStatement();
          myPackageName = name = statement == null ? "" : statement.getPackageName();
        }
        return name;
      }
    );
  }

  @Override
  public void setPackageName(@NotNull String packageName) throws IncorrectOperationException {
    if (PsiUtil.isModuleFile(this)) {
      throw new IncorrectOperationException("Cannot set package name for module declarations");
    }

    PsiPackageStatement packageStatement = getPackageStatement();
    PsiElementFactory factory = JavaPsiFacade.getElementFactory(getProject());
    if (packageStatement != null) {
      if (!packageName.isEmpty()) {
        PsiJavaCodeReferenceElement reference = packageStatement.getPackageReference();
        reference.replace(factory.createPackageStatement(packageName).getPackageReference());
      }
      else {
        packageStatement.delete();
      }
    }
    else if (!packageName.isEmpty()) {
      cleanupBrokenPackageKeyword();
      PsiElement anchor = getFirstChild();
      if (PsiPackage.PACKAGE_INFO_FILE.equals(getName())) {
        // If javadoc is already present in a package-info.java file, try to position the new package statement after it,

View on GitHub (pinned to be881553f2)

Solutions

  1. Skip module declaration files before the call: check PsiUtil.isModuleFile(psiFile) or file.getName().equals(JavaModuleFileType.MODULE_INFO_FILE) / "module-info.java".
  2. When moving a package, update module-info.java explicitly (requires-info, exports statements) instead of setPackageName.
  3. Use the IDE's standard Move refactoring, which already handles module descriptors specially.

Example fix

// before
psiJavaFile.setPackageName("org.newpkg"); // throws for module-info.java

// after
if (!PsiUtil.isModuleFile(psiJavaFile)) {
  psiJavaFile.setPackageName("org.newpkg");
} else {
  // update module-info contents (exports/requires) separately
}
Defensive patterns

Strategy: validation

Validate before calling

if (PsiUtil.isModuleFile(psiJavaFile)) return; // module-info: no setPackageName

Type guard

static boolean isModuleDescriptor(PsiJavaFile f) { return PsiUtil.isModuleFile(f); }

Try / catch

try { file.setPackageName(p); } catch (IncorrectOperationException e) { /* handle module-info separately */ }

Prevention

When it happens

Trigger: Calling PsiJavaFile.setPackageName (directly or via refactoring APIs like JavaPsiFacade/refactor move that retarget package) on a file named module-info.java.

Common situations: Move/refactor package operations applied blindly to all files in a directory including module-info.java; plugins that 'normalize' package statements across a source root; scripts that migrate packages and hit JPMS descriptors.

Related errors


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