discordjs/discord.js · error · Error
One or more packages have dependents that can't be released:
Error message
One or more packages have dependents that can't be released: ${unreleased.map((entry) => entry.name).join(',')} What it means
During tree generation, packages whose dependencies have not yet been released are deferred to a later layer. If a full pass completes with no progress (releaseEntries.length === unreleased.length), the remaining packages are deadlocked: their dependents can never be released, so the algorithm throws listing the stuck packages.
Source
Thrown at packages/actions/src/releasePackages/generateReleaseTree.ts:176
nextBranch.push(entry);
continue;
}
const allDepsReleased = entry.dependsOn.every((dep) => didRelease.has(dep));
if (allDepsReleased) {
nextBranch.push(entry);
} else {
unreleased.push(entry);
}
}
// Update didRelease in a second loop to avoid loop order issues
for (const release of nextBranch) {
didRelease.add(release.name);
}
if (releaseEntries.length === unreleased.length) {
throw new Error(
`One or more packages have dependents that can't be released: ${unreleased.map((entry) => entry.name).join(',')}`,
);
}
releaseTree.push(nextBranch);
releaseEntries = unreleased;
}
// Prune exclusions
if ((!packageName || packageName === 'all') && Array.isArray(exclude) && exclude.length) {
const neededPackages = new Set<string>();
const excludedReleaseTree: ReleaseEntry[][] = [];
for (const releaseBranch of releaseTree.reverse()) {
const newThisBranch: ReleaseEntry[] = [];
for (const entry of releaseBranch) {
if (exclude.includes(entry.name) && !neededPackages.has(entry.name)) {View on GitHub (pinned to a81ed8a306)
Solutions
- Remove the offending package from the --exclude list so its dependents can be released after it.
- Inspect the listed unreleased packages' dependsOn graphs for circular dependencies and break the cycle.
- Release the dependency packages first in a separate run, then release the dependents.
- Check recently changed inter-package dependencies for accidental or malformed dependsOn entries.
Example fix
// before pnpm release all --exclude=@discordjs/builders // node-packages depend on builders -> deadlock // after pnpm release all // release dependencies in correct topological order
Defensive patterns
Strategy: validation
Validate before calling
const excluded = new Set(exclude ?? []);
for (const name of plannedNames) {
const entry = entries.find((e) => e.name === name);
if (entry?.dependsOn?.some((d) => excluded.has(d))) {
throw new Error(`${name} depends on excluded package; deadlock risk`);
}
} Type guard
const hasExcludedDep = (entry: { dependsOn?: string[] }, excluded: Set<string>) =>
entry.dependsOn?.some((d) => excluded.has(d)) ?? false; Try / catch
try {
const tree = await generateReleaseTree(dry, tag, packageName, exclude);
} catch (err) {
if ((err as Error).message.includes("dependents that can't be released")) {
console.error('Release graph is deadlocked; check --exclude and dependsOn cycles.');
} else throw err;
} Prevention
- Never exclude a package that other pending packages depend on.
- Keep inter-package dependency graphs acyclic.
- Release dependencies before dependents when doing partial releases.
When it happens
Trigger: Building a release tree where one or more packages depend on another package that itself cannot be released (cycle in dependsOn, or a dependency excluded via --exclude that a remaining package requires), so no nextBranch can be formed and entries stop shrinking.
Common situations: Using --exclude on a package that other to-be-released packages depend on; circular dependencies between packages introduced by a refactor; malformed dependsOn metadata in a package.
Related errors
AI-assisted analysis of discordjs/discord.js@a81ed8a306 (2026-08-30).
Data as JSON: /api/errors/e6919c9566bd9646.
Report an issue: GitHub.