pnpm/pnpm · error · PnpmError
SCRIPT_OVERRIDE_IN_WORKSPACE_ROOT
SCRIPT_OVERRIDE_IN_WORKSPACE_ROOT
Error message
The workspace root has a "${typedCommandName}" script, so the built-in "pnpm ${typedCommandName}" command cannot run from a subdirectory What it means
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.
Source
Thrown at pnpm11/pnpm/src/main.ts:242
const currentDirManifest = config.dir === context.rootProjectManifestDir
? context.rootProjectManifest
: await safeReadProjectManifestOnly(config.dir)
if (currentDirManifest?.scripts?.[typedCommandName]) {
// Redirect to "pnpm run <cmd>"
cmd = 'run'
cliParams.unshift(typedCommandName)
fallbackCommandUsed = true
config.fallbackCommandUsed = true
config.extraEnv = {
...config.extraEnv,
npm_command: 'run-script',
}
} else if (
workspaceDir &&
config.dir !== context.rootProjectManifestDir &&
context.rootProjectManifest?.scripts?.[typedCommandName]
) {
throw new PnpmError(
'SCRIPT_OVERRIDE_IN_WORKSPACE_ROOT',
`The workspace root has a "${typedCommandName}" script, ` +
`so the built-in "pnpm ${typedCommandName}" command cannot run from a subdirectory`,
{
hint: `Run "pnpm run ${typedCommandName}" from the workspace root to execute the script`,
}
)
}
}
if (
cmd != null && recursiveByDefaultCommands.has(cmd) &&
typeof workspaceDir === 'string'
) {
cliOptions['recursive'] = true
config.recursive = true
if (!config.recursiveInstall && !config.filter && !config.filterProd) {View on GitHub (pinned to 6261b7f388)
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>`
Example fix
# before -- cwd is packages/foo, root package.json defines a "test" script pnpm test # after cd <workspace-root> && pnpm run test # or: pnpm --filter foo run test
Defensive patterns
Strategy: validation
Validate before calling
import { readFileSync } from 'node:fs'
const localScripts: Record<string, string> =
JSON.parse(readFileSync('package.json', 'utf8')).scripts ?? {}
if (overridable.includes(name) && !(name in localScripts) && process.cwd() !== workspaceRoot) {
// `pnpm <name>` will throw here - go to the root or use pnpm run explicitly
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- ERR_PNPM_NO_SCRIPT
- ERR_PNPM_RECURSIVE_RUN_NO_SCRIPT
- ADDING_TO_ROOT
- PKG_RECURSIVE_NO_ROOT
- OPTIONS_CONFLICT
AI-assisted analysis of pnpm/pnpm@6261b7f388 (2026-08-17).
Data as JSON: /api/errors/0f881cbdfd5c060b.
Report an issue: GitHub.