dependsOn silently drops any target whose name contains `[` (breaks @nx/jest Atomizer on Next.js dynamic routes)
@AgentEnder is already working on this.
Since Aug 13, 2026.
- Dominant language
- TypeScript
- Stars
- 29.4k
- Forks
- 3k
- Avg merge
- 2d 13h
- Merged PRs (30d)
- 153
Description
Current Behavior
A dependsOn entry naming a target whose name contains [ is silently dropped from the task graph. The target exists, runs fine when invoked directly, and is listed in dependsOn — but it never runs as a dependency. No warning, exit code 0.
This is not a niche naming choice: the @nx/jest Atomizer generates one target per test file, so any project with Next.js App Router dynamic routes gets targets like test-ci--src/app/projects/[id]/page.test.tsx. Every one of those is dropped.
In our monorepo this meant 57 test files (~611 tests) never executed in CI while CI stayed green. They were only noticed because one of them had been failing locally for weeks against a green CI.
Expected Behavior
Either the exact target name resolves (preferred — the name is an exact match for an existing target), or Nx warns that a dependsOn pattern matched no targets. Silent omission of declared work is the harmful part.
Note there is already a warning for the analogous project case — Project patterns "..." does not match any projects. in processTasksForMultipleProjects. The target case has no equivalent.
Minimal Reproduction
packages/demo/project.json:
{
"name": "demo",
"targets": {
"parent": {
"executor": "nx:noop",
"dependsOn": ["child--plain.test.ts", "child--src/app/[id]/page.test.ts"]
},
"child--plain.test.ts": {
"executor": "nx:run-commands",
"options": { "command": "echo RAN plain" }
},
"child--src/app/[id]/page.test.ts": {
"executor": "nx:run-commands",
"options": { "command": "echo RAN bracketed" }
}
}
}
$ nx run demo:parent
NX Running target parent for project demo and 1 task it depends on:
> echo RAN plain
RAN plain
NX Successfully ran target parent for project demo and 1 task it depends on
Two dependencies declared, one scheduled. RAN bracketed never prints. Exits 0.
Root Cause
expandWildcardTargetConfiguration in packages/nx/src/tasks-runner/utils.ts:
function expandWildcardTargetConfiguration(dependencyConfig, allTargetNames) {
if (!isGlobPattern(dependencyConfig.target)) {
return [dependencyConfig];
}
const matchingTargets = findMatchingTargets(dependencyConfig.target, allTargetNames);
return matchingTargets.map((t) => ({ ...dependencyConfig, target: t }));
}
isGlobPattern (packages/nx/src/utils/globs.ts) returns true if the string contains any character in GLOB_CHARACTERS, which includes [:
export const GLOB_CHARACTERS = new Set(['*', '|', '{', '}', '(', ')', '[']);
So the name is routed to findMatchingTargets, which uses minimatch.filter(pattern). [id] is a character class matching a single i or d, so the pattern matches nothing — not even its own literal name:
const p = 'test-ci--src/app/projects/[id]/page.test.tsx';
minimatch(p, p); // false
minimatch(p.replace('[id]', 'i'), p); // true
matchingTargets is empty, so the config expands to [] and the dependency disappears. The exact-name gate at projectHasTarget is never reached, and the target is present in the project graph throughout.
Possible Fix
Prefer an exact match before treating the name as a glob, e.g. in expandWildcardTargetConfiguration:
if (allTargetNames.includes(dependencyConfig.target)) {
return [dependencyConfig];
}
That keeps wildcard dependsOn working while making a name that exactly identifies a real target always resolve. Failing that, warning when a target pattern matches zero targets would at least make it visible.
Environment
- Nx 23.0.2. Verified 23.1.0 ships identical
expandWildcardTargetConfigurationandGLOB_CHARACTERS, so upgrading does not help. - Reproduced on macOS, Node 24.16.0.
- Surfaces via
@nx/jestciTargetName(Atomizer) + Next.js App Router dynamic route dirs, but the repro above needs neither plugin.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.