yarnpkg/yarn · error · MessageError
workspacesAddRootCheck
Error message
workspacesAddRootCheck
What it means
Thrown by `yarn add` when the current working directory is the workspace root folder. Yarn blocks this because adding a dependency at the root would mutate the root manifest rather than any individual workspace package, which is rarely intended. The lang string reads: 'Running this command will add the dependency to the workspace root rather than the workspace itself ... make it explicit by running this command again with the -W flag'. The guard is opt-out: pass `-W` / `--ignore-workspace-root-check` to bypass it.
Source
Thrown at src/cli/commands/add.js:178
const match = await this.integrityChecker.check(patterns, lockfileCache, this.flags, workspaceLayout);
const haveLockfile = await fs.exists(path.join(this.config.lockfileFolder, constants.LOCKFILE_FILENAME));
if (match.integrityFileMissing && haveLockfile) {
// Integrity file missing, force script installations
this.scripts.setForce(true);
}
return false;
}
/**
* Description
*/
async init(): Promise<Array<string>> {
const isWorkspaceRoot = this.config.workspaceRootFolder && this.config.cwd === this.config.workspaceRootFolder;
// running "yarn add something" in a workspace root is often a mistake
if (isWorkspaceRoot && !this.flags.ignoreWorkspaceRootCheck) {
throw new MessageError(this.reporter.lang('workspacesAddRootCheck'));
}
this.addedPatterns = [];
const patterns = await Install.prototype.init.call(this);
await this.maybeOutputSaveTree(patterns);
return patterns;
}
async applyChanges(manifests: RootManifests): Promise<boolean> {
await Install.prototype.applyChanges.call(this, manifests);
// fill rootPatternsToOrigin without `excludePatterns`
await Install.prototype.fetchRequestFromCwd.call(this);
this._iterateAddedPackages((pattern, registry, dependencyType, pkgName, version) => {
// add it to manifest
const {object} = manifests[registry];
View on GitHub (pinned to c2dda503f3)
Solutions
- `cd` into the specific workspace package directory and re-run `yarn add <pkg>`.
- If you genuinely want a root-level dependency, re-run with `yarn add -W <pkg>` (or `--ignore-workspace-root-check`).
- Verify `process.cwd()` and `config.workspaceRootFolder` programmatically before invoking `Add` to surface intent early.
Example fix
// before $ yarn add lodash // run from monorepo root // after (per-workspace) $ cd packages/my-app && yarn add lodash // after (root-level, explicit) $ yarn add -W lodash
Defensive patterns
Strategy: validation
Validate before calling
// Before calling Add, confirm intent if at workspace root
import path from 'path';
function assertAddTarget(config, flags) {
const atRoot = config.workspaceRootFolder && config.cwd === config.workspaceRootFolder;
if (atRoot && !flags.ignoreWorkspaceRootCheck) {
throw new Error(
`Refusing yarn add at workspace root ${config.cwd}. ` +
`cd into a workspace package, or set flags.ignoreWorkspaceRootCheck = true.`
);
}
}
// assertAddTarget(config, flags); // run before new Add(...).init() Type guard
function isWorkspaceRoot(config): boolean {
return Boolean(config.workspaceRootFolder) && config.cwd === config.workspaceRootFolder;
} Try / catch
try {
await install.init();
} catch (e) {
if (e.message && e.message.includes('workspace root rather than the workspace')) {
// prompt user to cd into a workspace or pass -W
} else throw e;
} Prevention
- Always cd into the target workspace package before `yarn add`.
- In CI/scripts, assert `process.cwd()` is a workspace subdirectory, not the root.
- Document the -W escape hatch so root-level adds are deliberate.
When it happens
Trigger: `this.config.cwd === this.config.workspaceRootFolder` is true AND `this.flags.ignoreWorkspaceRootCheck` is falsy at the start of `Add.init()`. This happens when a project root declares `workspaces` in package.json and you run `yarn add <pkg>` from that root.
Common situations: Developer in a monorepo runs `yarn add lodash` from the repo root by habit, intending to add it to one workspace package. Also triggered when shell `cwd` is the repo root but the target package lives in a subdirectory.
Related errors
AI-assisted analysis of yarnpkg/yarn@c2dda503f3 (2026-08-13).
Data as JSON: /api/errors/fc6a07cfba2ce4b5.
Report an issue: GitHub.