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

  1. Remove "private": true (or set it to false) in the package.json that is meant to be published
  2. If the package must stay private, exclude it from the publish pipeline (filter on pkg.private in your release script)
  3. 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

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


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/e30a96ea9eac3701. Report an issue: GitHub.