JetBrains/intellij-community · error · IncorrectOperationException

File name must end with .

Error message

File name must end with .

What it means

For @snippet javadoc tags whose region/file attribute declares a required file extension (e.g. region files expected to be .java), bindToElement verifies the target file's relative path ends with that extension. If it does not, it throws IncorrectOperationException("File name must end with .<ext>: <file>").

Source

Thrown at java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiSnippetAttributeValueImpl.java:234

    @Override
    public PsiElement handleElementRename(@NotNull String newElementName) throws IncorrectOperationException {
      // TODO
      return null;
    }

    @Override
    public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
      if (!(element instanceof PsiFile)) throw new IncorrectOperationException("PsiFile expected");
      if (isReferenceTo(element)) return PsiSnippetAttributeValueImpl.this;
      VirtualFile virtualFile = ((PsiFile)element).getVirtualFile();
      String relativePath = VfsUtilCore.getRelativePath(virtualFile, mySnippetRoot, '.');
      if (relativePath == null) {
        throw new IncorrectOperationException("File not in " + mySnippetRoot + ": " + virtualFile);
      }
      if (myExtension != null) {
        if (!StringUtil.endsWithIgnoreCase(relativePath, "." + myExtension)) {
          throw new IncorrectOperationException("File name must end with ." + myExtension + ": " + virtualFile);
        }
        relativePath = relativePath.substring(0, relativePath.length() - myExtension.length() - 1);
      }
      String newText;
      if (!relativePath.contains(mySeparator)) {
        newText = relativePath;
      }
      else if (getText().startsWith("'")) {
        newText = "'" + relativePath + "'";
      }
      else {
        newText = "\"" + relativePath + "\"";
      }
      ASTNode node = getNode();
      LeafElement newNode = ChangeUtil.copyLeafWithText((LeafElement)node, newText);
      node.getTreeParent().replaceChild(node, newNode);
      return newNode.getPsi();
    }

View on GitHub (pinned to be881553f2)

Solutions

  1. Bind only to files with the expected extension: check virtualFile.getName().endsWith("." + expectedExt) first.
  2. If you intentionally changed the snippet language, update or remove the extension constraint in the @snippet attribute before rebinding.
  3. Keep one snippet directory per language so refactors cannot cross-bind mismatched types.

Example fix

// before
snippetAttrRef.bindToElement(txtFile); // reference expects .java -> throws

// after
if (virtualFile.getName().endsWith("." + expectedExtension)) {
  snippetAttrRef.bindToElement(txtFile);
} else {
  // pick a matching .java snippet or adjust the @snippet attribute
}
Defensive patterns

Strategy: validation

Validate before calling

if (!vf.getName().endsWith("." + expectedExtension)) return; // extension mismatch

Try / catch

try { snippetRef.bindToElement(f); } catch (IncorrectOperationException e) { /* pick file with matching extension */ }

Prevention

When it happens

Trigger: Calling bindToElement on a snippet file reference that requires extension X (myExtension, e.g. "java") with a target PsiFile whose name does not end with .X — e.g. binding a .txt or .kts file to a reference declared for .java snippets.

Common situations: Move/rename refactorings that rebind snippet references to files of a different type; mixing languages in snippet directories (java snippets vs properties files); manual edits of the @snippet attribute followed by IDE refactors.

Related errors


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