{"record":{"id":"e6919c9566bd9646","repo":"discordjs/discord.js","slug":"one-or-more-packages-have-dependents-that-can-t-be","errorCode":null,"errorMessage":"One or more packages have dependents that can't be released: ${unreleased.map((entry) => entry.name).join(',')}","messagePattern":"One or more packages have dependents that can't be released: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/actions/src/releasePackages/generateReleaseTree.ts","lineNumber":176,"sourceCode":"\t\t\t\tnextBranch.push(entry);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst allDepsReleased = entry.dependsOn.every((dep) => didRelease.has(dep));\n\t\t\tif (allDepsReleased) {\n\t\t\t\tnextBranch.push(entry);\n\t\t\t} else {\n\t\t\t\tunreleased.push(entry);\n\t\t\t}\n\t\t}\n\n\t\t// Update didRelease in a second loop to avoid loop order issues\n\t\tfor (const release of nextBranch) {\n\t\t\tdidRelease.add(release.name);\n\t\t}\n\n\t\tif (releaseEntries.length === unreleased.length) {\n\t\t\tthrow new Error(\n\t\t\t\t`One or more packages have dependents that can't be released: ${unreleased.map((entry) => entry.name).join(',')}`,\n\t\t\t);\n\t\t}\n\n\t\treleaseTree.push(nextBranch);\n\t\treleaseEntries = unreleased;\n\t}\n\n\t// Prune exclusions\n\tif ((!packageName || packageName === 'all') && Array.isArray(exclude) && exclude.length) {\n\t\tconst neededPackages = new Set<string>();\n\t\tconst excludedReleaseTree: ReleaseEntry[][] = [];\n\n\t\tfor (const releaseBranch of releaseTree.reverse()) {\n\t\t\tconst newThisBranch: ReleaseEntry[] = [];\n\n\t\t\tfor (const entry of releaseBranch) {\n\t\t\t\tif (exclude.includes(entry.name) && !neededPackages.has(entry.name)) {","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/discordjs/discord.js/blob/a81ed8a306d37fdc746e26a634b6a42164ba2c8c/packages/actions/src/releasePackages/generateReleaseTree.ts#L158-L194","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\npnpm release all --exclude=@discordjs/builders   // node-packages depend on builders -> deadlock\n// after\npnpm release all   // release dependencies in correct topological order","handlingStrategy":"validation","validationCode":"const excluded = new Set(exclude ?? []);\nfor (const name of plannedNames) {\n  const entry = entries.find((e) => e.name === name);\n  if (entry?.dependsOn?.some((d) => excluded.has(d))) {\n    throw new Error(`${name} depends on excluded package; deadlock risk`);\n  }\n}","typeGuard":"const hasExcludedDep = (entry: { dependsOn?: string[] }, excluded: Set<string>) =>\n  entry.dependsOn?.some((d) => excluded.has(d)) ?? false;","tryCatchPattern":"try {\n  const tree = await generateReleaseTree(dry, tag, packageName, exclude);\n} catch (err) {\n  if ((err as Error).message.includes(\"dependents that can't be released\")) {\n    console.error('Release graph is deadlocked; check --exclude and dependsOn cycles.');\n  } else throw err;\n}","preventionTips":["Never exclude a package that other pending packages depend on.","Keep inter-package dependency graphs acyclic.","Release dependencies before dependents when doing partial releases."],"tags":["release","dependencies","cycle"],"backgroundTag":"dependency-release-deadlock","analyzedSha":"a81ed8a306d37fdc746e26a634b6a42164ba2c8c","analyzedAt":"2026-08-30T04:07:22.193Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}