bazelbuild/bazel · error · RuntimeException
No filter expression specified after ${arg}
Error message
No filter expression specified after ${arg} What it means
Thrown by JUnit4Options.parseArgs when a filter option that expects a separate value argument (e.g. --test_filter or --test_exclude_filter) is the last token on the command line. The parser sees the option name, calls it.next() to read the regular expression, and finds no more arguments, so it throws a RuntimeException rather than silently ignoring the filter.
Source
Thrown at src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4Options.java:66
Map<String, String> optionsMap = new HashMap<>();
optionsMap.put(TEST_INCLUDE_FILTER_OPTION, null);
optionsMap.put(TEST_EXCLUDE_FILTER_OPTION, null);
for (Iterator<String> it = args.iterator(); it.hasNext();) {
String arg = it.next();
int indexOfEquals = arg.indexOf("=");
if (indexOfEquals > 0) {
String optionName = arg.substring(0, indexOfEquals);
if (optionsMap.containsKey(optionName)) {
optionsMap.put(optionName, arg.substring(indexOfEquals + 1));
continue;
}
} else if (optionsMap.containsKey(arg)) {
// next argument is the regexp
if (!it.hasNext()) {
throw new RuntimeException("No filter expression specified after " + arg);
}
optionsMap.put(arg, it.next());
continue;
}
unparsedArgs.add(arg);
}
// If TESTBRIDGE_TEST_ONLY is set in the environment, forward it to the
// --test_filter flag.
String testFilter = envVars.get(TESTBRIDGE_TEST_ONLY);
if (testFilter != null && optionsMap.get(TEST_INCLUDE_FILTER_OPTION) == null) {
optionsMap.put(TEST_INCLUDE_FILTER_OPTION, testFilter);
}
boolean testRunnerFailFast = "1".equals(envVars.get(TESTBRIDGE_TEST_RUNNER_FAIL_FAST));
return new JUnit4Options(
testRunnerFailFast,
optionsMap.get(TEST_INCLUDE_FILTER_OPTION),
optionsMap.get(TEST_EXCLUDE_FILTER_OPTION),
unparsedArgs.toArray(new String[0]));View on GitHub (pinned to e6e199d060)
Solutions
- Use the equals form so the value is part of the token: --test_filter=com.foo.MyTest#method.
- If the value comes from a variable, guard it so the flag is only appended when the variable is non-empty.
- Pass the filter via the TESTBRIDGE_TEST_ONLY environment variable instead, which the runner forwards to --test_filter when no explicit filter is present.
Example fix
# before
java ... JUnit4Runner --test_filter $TESTS # TESTS empty -> flag dangles
# after
FILTER=${TESTS:+--test_filter=$TESTS}
java ... JUnit4Runner $FILTER Defensive patterns
Strategy: validation
Validate before calling
// before JUnit4Options.parseArgs
for (int i = 0; i < args.length; i++) {
if (args[i].equals("--test_filter") || args[i].equals("--test_exclude_filter")) {
if (i + 1 >= args.length || args[i + 1].startsWith("--")) {
throw new IllegalArgumentException("Missing value for " + args[i]);
}
}
} Try / catch
try {
JUnit4Options.parseArgs(Arrays.asList(args), env);
} catch (RuntimeException e) {
if (e.getMessage().startsWith("No filter expression")) { /* surface usage error */ }
} Prevention
- Prefer the --flag=value form for all junitrunner filter flags.
- Build argument lists conditionally: only append --test_filter when the variable is non-empty.
- Use TESTBRIDGE_TEST_ONLY for externally supplied filters.
When it happens
Trigger: Invoking JUnit4Options.parseArgs(args, envVars) with args ending in "--test_filter" (or another space-separated option key) with no following value, e.g. args = ["--test_filter"].
Common situations: Shell scripts or bazel run invocations that build the filter from a variable which expands to empty at the end of the line (RUNNER_ARGS="--test_filter $FILTER" with FILTER unset); typo'd flag split across lines in CI config.
Related errors
- Unsupported JUnit Runner API version ${JUNIT_API_VERSION_PRO
- Could not write exit file at ${file}
- Variable definitions must be in the form of a 'name=value' a
- Must be in the form of a 'key=value[,value]' assignment
- Error writing shard file ${shardFile}
AI-assisted analysis of bazelbuild/bazel@e6e199d060 (2026-08-14).
Data as JSON: /api/errors/2bce2e5c9a4753c5.
Report an issue: GitHub.