junit-team/junit5 · error · JUnitException
Expected file name with file extension, but got
Error message
Expected file name with file extension, but got: ${fileName} What it means
JUnitException thrown by SearchPathUtils.removeExtension when a file name contains no '.' (no extension). removeExtension is called from determineSimpleClassName and isModuleInfoOrPackageInfo during module classpath scanning. The upstream filter only passes .class/.java files (which always have extensions), so reaching this guard means an extension-less name slipped through filtering - a defensive failure.
Solutions
- Ensure the path is a .class/.java file before invoking SearchPathUtils.determineSimpleClassName
- If reached through standard scanning, report a bug to JUnit with the offending classpath/module entry
- Remove non-class files from module or jar entries that should not be scanned
Defensive patterns
Strategy: validation
Validate before calling
if (fileName.indexOf('.') < 0) {
// skip - not a class/source file; do not call removeExtension
} Prevention
- Keep module/jar entries to .class/.java files only
- Do not invoke SearchPathUtils internals on arbitrary paths
- Clean build outputs of stray extension-less files
When it happens
Trigger: A path whose final segment has no '.' reaches SearchPathUtils.removeExtension - e.g. via custom calling code invoking SearchPathUtils internals directly, or an upstream filter bug that lets an extension-less file through to class-name derivation.
Common situations: Rare; would indicate either a custom caller of SearchPathUtils internals on an arbitrary path, a malformed module entry, or a bug in upstream filtering. Standard scanning pre-filters to .class/.java which always have extensions.
Related errors
- Failed to create file system for
- Could not open color palette properties file
- Error redirecting stderr to file
- Error redirecting stdout and stderr to file
- Error redirecting stdout to file
AI-assisted analysis of junit-team/junit5@f070c699a0 (2026-08-11).
Data as JSON: /api/errors/636b4283ab137d85.
Report an issue: GitHub.
Appendix: source
Thrown at junit-platform-commons/src/main/java/org/junit/platform/commons/util/SearchPathUtils.java:72
var simpleClassName = determineSimpleClassName(path);
var parent = path.getParent();
return parent == null ? simpleClassName : joinPathNamesWithPackageSeparator(parent.resolve(simpleClassName));
}
private static String joinPathNamesWithPackageSeparator(Path path) {
return IntStream.range(0, path.getNameCount()) //
.mapToObj(i -> path.getName(i).toString()) //
.collect(joining(PACKAGE_SEPARATOR_STRING));
}
static String determineSimpleClassName(Path file) {
return removeExtension(file.getFileName().toString());
}
private static String removeExtension(String fileName) {
int lastDot = fileName.lastIndexOf(FILE_NAME_EXTENSION_SEPARATOR_CHAR);
if (lastDot < 0) {
throw new JUnitException("Expected file name with file extension, but got: " + fileName);
}
return fileName.substring(0, lastDot);
}
private static boolean isClassOrSourceFile(String name) {
return name.endsWith(CLASS_FILE_SUFFIX) || (SOURCE_MODE && name.endsWith(SOURCE_FILE_SUFFIX));
}
private static boolean isClassFile(Path file) {
return file.getFileName().toString().endsWith(CLASS_FILE_SUFFIX);
}
private SearchPathUtils() {
}
}
View on GitHub (pinned to f070c699a0)