paperclipai/paperclip · error · Error
Circular workspace dependency while staging
Error message
Circular workspace dependency while staging ${packageName}. What it means
Error "Circular workspace dependency while staging ${packageName}." thrown in paperclipai/paperclip.
Solutions
- Fix the circular dependency between workspace packages in scripts/release-package-manifest.json.
When it happens
Trigger: Thrown at cli/src/commands/install.ts:65 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-08-18).
Data as JSON: /api/errors/9af244b872bbfe14.
Report an issue: GitHub.
Appendix: source
Thrown at cli/src/commands/install.ts:66
const stderr = error && typeof error === "object" && "stderr" in error && typeof error.stderr === "string"
? error.stderr.trim()
: "";
if (!stderr || (error instanceof Error && error.message.includes(stderr))) throw error;
throw new Error(`${error instanceof Error ? error.message : String(error)}\n${stderr}`, { cause: error });
}
}
export function resolveGitInstallWorkspacePackages(checkoutPath: string): ReleasePackageEntry[] {
const manifestPath = path.join(checkoutPath, "scripts", "release-package-manifest.json");
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8")) as ReleasePackageEntry[];
const packageByName = new Map(manifest.map((entry) => [entry.name, entry]));
const visiting = new Set<string>();
const visited = new Set<string>();
const ordered: ReleasePackageEntry[] = [];
const visit = (packageName: string): void => {
if (visited.has(packageName)) return;
if (visiting.has(packageName)) throw new Error(`Circular workspace dependency while staging ${packageName}.`);
const entry = packageByName.get(packageName);
if (!entry) throw new Error(`Git install cannot stage workspace dependency ${packageName}; it is missing from scripts/release-package-manifest.json.`);
visiting.add(packageName);
const packageJson = JSON.parse(fs.readFileSync(path.join(checkoutPath, entry.dir, "package.json"), "utf8")) as Record<string, unknown>;
for (const section of ["dependencies", "optionalDependencies", "peerDependencies"] as const) {
const dependencies = packageJson[section];
if (!dependencies || typeof dependencies !== "object") continue;
for (const dependencyName of Object.keys(dependencies)) {
if (dependencyName.startsWith("@paperclipai/")) visit(dependencyName);
}
}
visiting.delete(packageName);
visited.add(packageName);
ordered.push(entry);
};
visit("@paperclipai/server");
return ordered;View on GitHub (pinned to 01ad858492)