yarnpkg/yarn · error · MessageError

nohoist config is ignored in $0 because it is not a private

Error message

nohoist config is ignored in $0 because it is not a private package. If you think nohoist should be allowed in public packages, please submit an issue for your use case.

What it means

Thrown by `getWorkspaces` (when `shouldThrow` is true) if the `nohoist` array is non-empty on a package that is not `private: true`. The errors array collects the `workspacesNohoistRequirePrivatePackages` message; since `resolveWorkspaces` calls `getWorkspaces(rootManifest, true)`, the throw fires at the root. Nohoist is considered a workspace-internal concern only valid for private packages.

Source

Thrown at src/config.js:889

    // packages
    if (wsCopy.packages && wsCopy.packages.length > 0 && !manifest.private) {
      errors.push(this.reporter.lang('workspacesRequirePrivateProjects'));
      wsCopy = undefined;
    }
    // nohoist
    if (wsCopy && wsCopy.nohoist && wsCopy.nohoist.length > 0) {
      if (!this.workspacesNohoistEnabled) {
        warnings.push(this.reporter.lang('workspacesNohoistDisabled', manifest.name));
        wsCopy.nohoist = undefined;
      } else if (!manifest.private) {
        errors.push(this.reporter.lang('workspacesNohoistRequirePrivatePackages', manifest.name));
        wsCopy.nohoist = undefined;
      }
    }

    if (errors.length > 0 && shouldThrow) {
      throw new MessageError(errors.join('\n'));
    }

    const msg = errors.concat(warnings).join('\n');
    if (msg.length > 0) {
      this.reporter.warn(msg);
    }

    return wsCopy;
  }

  /**
   * Description
   */

  getFolder(pkg: Manifest): string {
    let registryName = pkg._registry;
    if (!registryName) {
      const ref = pkg._reference;

View on GitHub (pinned to c2dda503f3)

Solutions

  1. Add `"private": true` to the package.json that declares `nohoist`.
  2. Remove the `nohoist` field if the package is meant to be published publicly.
  3. If nohoist is needed only in private workspaces, keep the root private and scope nohoist appropriately.

Example fix

// before (package.json)
{
  "name": "my-pkg",
  "workspaces": { "nohoist": ["react-native"] }
}
// after
{
  "name": "my-pkg",
  "private": true,
  "workspaces": { "nohoist": ["react-native"] }
}
Defensive patterns

Strategy: validation

Validate before calling

const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
const ws = pkg.workspaces;
const hasNohoist = ws && (Array.isArray(ws) ? false : Array.isArray(ws.nohoist) && ws.nohoist.length > 0);
if (hasNohoist && !pkg.private) {
  throw new Error('nohoist requires "private": true in package.json.');
}

Type guard

function isPrivateWithNohoistAllowed(pkg) {
  return pkg.private === true || !(pkg.workspaces && pkg.workspaces.nohoist && pkg.workspaces.nohoist.length > 0);
}

Try / catch

try {
  config.getWorkspaces(manifest, true);
} catch (err) {
  if (err.message.includes('nohoist') && err.message.includes('private')) {
    reporter.error('Add "private": true or remove the nohoist field.');
    process.exit(1);
  }
  throw err;
}

Prevention

When it happens

Trigger: Root or sub-package package.json declares `"workspaces": {"nohoist": [...]}` (or per-workspace `nohoist`) but the package does not have `"private": true`.

Common situations: Publishing a package that still carries nohoist config from internal development. Copying a monorepo config into a public package. Forgetting `private: true` on a root that uses nohoist.

Related errors


AI-assisted analysis of yarnpkg/yarn@c2dda503f3 (2026-08-13). Data as JSON: /api/errors/562ef5bfaa7bc640. Report an issue: GitHub.