ruvnet/ruflo · error · Error
Cannot publish private package
Error message
Cannot publish private package
What it means
publishToNpm() refuses to publish when package.json contains "private": true. The npm registry would reject the publish anyway; the guard fails fast before the build step runs, saving a wasted build cycle.
Source
Thrown at v3/@claude-flow/deployment/src/publisher.ts:49
const result: PublishResult = {
packageName: '',
version: '',
tag,
success: false
};
try {
// Read package.json
const pkgPath = join(this.cwd, 'package.json');
if (!existsSync(pkgPath)) {
throw new Error('package.json not found');
}
const pkg: PackageInfo = JSON.parse(readFileSync(pkgPath, 'utf-8'));
if (pkg.private) {
throw new Error('Cannot publish private package');
}
result.packageName = pkg.name;
result.version = pkg.version;
// Run build if not skipped
if (!skipBuild) {
console.log('Building package...');
this.execCommand(buildCommand);
}
// Construct npm publish command arguments (without 'npm' prefix for execNpmCommand)
const publishArgs: string[] = ['publish'];
if (tag) {
publishArgs.push('--tag', tag);
}
View on GitHub (pinned to fa13ee4ad6)
Solutions
- Remove "private": true (or set it to false) in the package.json that is meant to be published
- If the package must stay private, exclude it from the publish pipeline (filter on pkg.private in your release script)
- For scoped public packages, also set publishConfig.access explicitly so the intent is recorded
Example fix
// before
// package.json: { "name": "@acme/util", "private": true }
await publisher.publishToNpm(); // throws: Cannot publish private package
// after
// package.json: { "name": "@acme/util", "publishConfig": { "access": "public" } }
await publisher.publishToNpm(); Defensive patterns
Strategy: validation
Validate before calling
import { readFileSync } from 'node:fs';
import { join } from 'node:path';
const pkg = JSON.parse(readFileSync(join(pkgDir, 'package.json'), 'utf8'));
if (pkg.private) {
throw new Error(`${pkg.name} is private — excluded from publish`);
}
await new Publisher(pkgDir).publishToNpm(); Type guard
function isPublishable(pkg: { private?: boolean }): boolean {
return pkg.private !== true;
} Prevention
- Keep an explicit publish allowlist of package paths in the release script instead of publishing every workspace package
- Flip private off deliberately in the same commit that first publishes
When it happens
Trigger: Any package.json with "private": true in the Publisher cwd — the default state for packages created inside an npm workspace (npm init -w) and for internal utilities.
Common situations: Monorepo leaf packages marked private by default; forgetting to flip the flag before a first public release; intentionally-private packages left in the release pipeline.
Related errors
- package.json not found
- Failed to import OpenAI
- Pinata upload failed (HTTP ${res.status}): ${JSON.stringify(
- module loaded but is missing expected OAuth exports
- ruflo auth needs the '@claude-flow/security' package, which
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/e30a96ea9eac3701.
Report an issue: GitHub.