{"record":{"id":"0f881cbdfd5c060b","repo":"pnpm/pnpm","slug":"script-override-in-workspace-root","errorCode":"SCRIPT_OVERRIDE_IN_WORKSPACE_ROOT","errorMessage":"The workspace root has a \"${typedCommandName}\" script, so the built-in \"pnpm ${typedCommandName}\" command cannot run from a subdirectory","messagePattern":"The workspace root has a \"(.+?)\" script, so the built-in \"pnpm (.+?)\" command cannot run from a subdirectory","errorType":"error_code","errorClass":"PnpmError","httpStatus":null,"severity":"error","filePath":"pnpm11/pnpm/src/main.ts","lineNumber":242,"sourceCode":"    const currentDirManifest = config.dir === context.rootProjectManifestDir\n      ? context.rootProjectManifest\n      : await safeReadProjectManifestOnly(config.dir)\n    if (currentDirManifest?.scripts?.[typedCommandName]) {\n      // Redirect to \"pnpm run <cmd>\"\n      cmd = 'run'\n      cliParams.unshift(typedCommandName)\n      fallbackCommandUsed = true\n      config.fallbackCommandUsed = true\n      config.extraEnv = {\n        ...config.extraEnv,\n        npm_command: 'run-script',\n      }\n    } else if (\n      workspaceDir &&\n      config.dir !== context.rootProjectManifestDir &&\n      context.rootProjectManifest?.scripts?.[typedCommandName]\n    ) {\n      throw new PnpmError(\n        'SCRIPT_OVERRIDE_IN_WORKSPACE_ROOT',\n        `The workspace root has a \"${typedCommandName}\" script, ` +\n        `so the built-in \"pnpm ${typedCommandName}\" command cannot run from a subdirectory`,\n        {\n          hint: `Run \"pnpm run ${typedCommandName}\" from the workspace root to execute the script`,\n        }\n      )\n    }\n  }\n\n  if (\n    cmd != null && recursiveByDefaultCommands.has(cmd) &&\n    typeof workspaceDir === 'string'\n  ) {\n    cliOptions['recursive'] = true\n    config.recursive = true\n\n    if (!config.recursiveInstall && !config.filter && !config.filterProd) {","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/pnpm/pnpm/blob/6261b7f388016d57ca6b90340342411cd1d0d00f/pnpm11/pnpm/src/main.ts#L224-L260","documentation":"For built-in commands that a project script can shadow (e.g. `pnpm start`, `pnpm test`), pnpm first checks the manifest of the current directory: if that project defines a same-named script, pnpm re-routes to `pnpm run <name>`. If it does not, but you are in a workspace subdirectory and the workspace root manifest defines that script, pnpm refuses to guess and throws SCRIPT_OVERRIDE_IN_WORKSPACE_ROOT, with a hint to run `pnpm run <cmd>` from the root.","triggerScenarios":"In a monorepo, the root package.json has a script named identically to a built-in command (e.g. `\"test\"`); you run `pnpm test` inside `packages/foo` whose own manifest has no `test` script, so there is nothing to re-route to locally but the root script collides.","commonSituations":"Monorepos that keep test/build orchestration at the root; behavior change after upgrading pnpm from versions that silently fell back to the root script; developers cd'ed deep into a workspace package.","solutions":["Run it from the workspace root: `pnpm run <cmd>` executes the root script, as the hint says","Define the script in the subproject's own package.json so `pnpm <cmd>` re-routes locally","Select the project explicitly from the root instead of relying on cwd: `pnpm --filter <pkg> run <cmd>`"],"exampleFix":"# before -- cwd is packages/foo, root package.json defines a \"test\" script\npnpm test\n\n# after\ncd <workspace-root> && pnpm run test\n# or: pnpm --filter foo run test","handlingStrategy":"validation","validationCode":"import { readFileSync } from 'node:fs'\n\nconst localScripts: Record<string, string> =\n  JSON.parse(readFileSync('package.json', 'utf8')).scripts ?? {}\n\nif (overridable.includes(name) && !(name in localScripts) && process.cwd() !== workspaceRoot) {\n  // `pnpm <name>` will throw here - go to the root or use pnpm run explicitly\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["In monorepos, call `pnpm run <cmd>` explicitly rather than the bare built-in name from subdirectories","Either mirror shared scripts into subpackages or always orchestrate from the workspace root","Treat root package.json script names as reserved for commands teams run from the root"],"tags":["workspace","scripts","command-shadowing","monorepo","cli"],"backgroundTag":"script-command-collision","analyzedSha":"6261b7f388016d57ca6b90340342411cd1d0d00f","analyzedAt":"2026-08-17T18:30:54.750Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}