denoland/deno · error · anyhow::Error
task name filter '{}' uses an exclusion group '(!...)' but h
Error message
task name filter '{}' uses an exclusion group '(!...)' but has no wildcard '*' to exclude from What it means
`deno task --filter` accepts glob patterns with exclusion groups, e.g. `test:*(!e2e|interactive)` runs every `test:*` task except the listed ones. The exclusion group is only meaningful when the pattern contains a wildcard to exclude from; a filter like `build(!lint)` has nothing to apply exclusions to, so the parser rejects it up front, echoing the input.
Source
Thrown at cli/tools/task.rs:1581
fn arg_to_task_name_filter(
input: &str,
) -> Result<TaskNameFilter<'_>, AnyError> {
// Parse an optional trailing exclusion group of the form `(!a|b|c)`.
// Exclusion values are matched against what each `*` in the pattern
// captures, e.g. `test:*(!e2e|interactive)` excludes `test:e2e` and
// `test:interactive` but still matches `test:unit`.
let (pattern, exclusions): (&str, Vec<&str>) = match input.rfind("(!") {
Some(open) if input.ends_with(')') => {
let inner = &input[open + 2..input.len() - 1];
(&input[..open], inner.split('|').collect())
}
_ => (input, Vec::new()),
};
if !pattern.contains('*') {
if !exclusions.is_empty() {
return Err(anyhow!(
"task name filter '{}' uses an exclusion group '(!...)' but has no wildcard '*' to exclude from",
input
));
}
return Ok(TaskNameFilter::Exact(input));
}
let mut regex_str = regex::escape(pattern);
regex_str = regex_str.replace("\\*", "(.*)");
regex_str = format!("^{}", regex_str);
let re = Regex::new(®ex_str)?;
let exclusions = exclusions.into_iter().map(String::from).collect();
Ok(TaskNameFilter::Regex { re, exclusions })
}
#[derive(Debug)]
enum TaskNameFilter<'s> {
Exact(&'s str),View on GitHub (pinned to 89f33cbef2)
Solutions
- Add the wildcard: use 'test*(!e2e)' instead of 'test(!e2e)'
- Drop the exclusion group and use the exact task name when no wildcard is needed
- Run `deno task` to see which names the pattern should match
Example fix
# before deno task --filter 'test(!e2e)' # after deno task --filter 'test*(!e2e)'
Defensive patterns
Strategy: validation
Validate before calling
# reject --filter values that use (!...) without a *
filter="$1"
case "$filter" in
*'(!'*)
case "$filter" in
*'*'*"(!"*) : ;;
*) echo "filter '$filter' needs a '*' before the exclusion group" >&2; exit 1 ;;
esac ;;
esac Prevention
- Remember the exclusion syntax `(!a|b)` only applies to wildcard matches
- Dry-check filter selection with `deno task` output before wiring into CI
- Prefer exact names or simple globs unless exclusions are truly needed
When it happens
Trigger: `deno task --filter 'name(!excluded)'` where the pattern before the `(!...)` group contains no `*` character.
Common situations: Assuming the exclusion syntax works on exact task names; typos dropping the `*`; adapting npm script-selection habits to deno task filters.
Related errors
- ERR_INVALID_ARG_TYPE
- No input files specified
- The bench name can't be empty
- Unexpected 'name' field in options, bench name is already pr
- Unexpected 'fn' field in options, bench function is already
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/abf61646b6fd132a.
Report an issue: GitHub.