{"record":{"id":"fc6a07cfba2ce4b5","repo":"yarnpkg/yarn","slug":"workspacesaddrootcheck","errorCode":null,"errorMessage":"workspacesAddRootCheck","messagePattern":"workspacesAddRootCheck","errorType":"exception","errorClass":"MessageError","httpStatus":null,"severity":"error","filePath":"src/cli/commands/add.js","lineNumber":178,"sourceCode":"    const match = await this.integrityChecker.check(patterns, lockfileCache, this.flags, workspaceLayout);\n    const haveLockfile = await fs.exists(path.join(this.config.lockfileFolder, constants.LOCKFILE_FILENAME));\n    if (match.integrityFileMissing && haveLockfile) {\n      // Integrity file missing, force script installations\n      this.scripts.setForce(true);\n    }\n    return false;\n  }\n\n  /**\n   * Description\n   */\n\n  async init(): Promise<Array<string>> {\n    const isWorkspaceRoot = this.config.workspaceRootFolder && this.config.cwd === this.config.workspaceRootFolder;\n\n    // running \"yarn add something\" in a workspace root is often a mistake\n    if (isWorkspaceRoot && !this.flags.ignoreWorkspaceRootCheck) {\n      throw new MessageError(this.reporter.lang('workspacesAddRootCheck'));\n    }\n\n    this.addedPatterns = [];\n    const patterns = await Install.prototype.init.call(this);\n    await this.maybeOutputSaveTree(patterns);\n    return patterns;\n  }\n\n  async applyChanges(manifests: RootManifests): Promise<boolean> {\n    await Install.prototype.applyChanges.call(this, manifests);\n\n    // fill rootPatternsToOrigin without `excludePatterns`\n    await Install.prototype.fetchRequestFromCwd.call(this);\n\n    this._iterateAddedPackages((pattern, registry, dependencyType, pkgName, version) => {\n      // add it to manifest\n      const {object} = manifests[registry];\n","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/yarnpkg/yarn/blob/c2dda503f3759b5be5f0e24ecd9cf5c97a540147/src/cli/commands/add.js#L160-L196","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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.","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."],"exampleFix":"// before\n$ yarn add lodash   // run from monorepo root\n\n// after (per-workspace)\n$ cd packages/my-app && yarn add lodash\n\n// after (root-level, explicit)\n$ yarn add -W lodash","handlingStrategy":"validation","validationCode":"// Before calling Add, confirm intent if at workspace root\nimport path from 'path';\n\nfunction assertAddTarget(config, flags) {\n  const atRoot = config.workspaceRootFolder && config.cwd === config.workspaceRootFolder;\n  if (atRoot && !flags.ignoreWorkspaceRootCheck) {\n    throw new Error(\n      `Refusing yarn add at workspace root ${config.cwd}. ` +\n      `cd into a workspace package, or set flags.ignoreWorkspaceRootCheck = true.`\n    );\n  }\n}\n// assertAddTarget(config, flags);  // run before new Add(...).init()","typeGuard":"function isWorkspaceRoot(config): boolean {\n  return Boolean(config.workspaceRootFolder) && config.cwd === config.workspaceRootFolder;\n}","tryCatchPattern":"try {\n  await install.init();\n} catch (e) {\n  if (e.message && e.message.includes('workspace root rather than the workspace')) {\n    // prompt user to cd into a workspace or pass -W\n  } else throw e;\n}","preventionTips":["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."],"tags":["workspaces","yarn-add","cli","guard"],"backgroundTag":null,"analyzedSha":"c2dda503f3759b5be5f0e24ecd9cf5c97a540147","analyzedAt":"2026-08-13T04:17:06.305Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}