{"record":{"id":"d98daebd041af3df","repo":"Budibase/budibase","slug":"npm-is-required-to-run-this-project-package-lock","errorCode":null,"errorMessage":"npm is required to run this project (package-lock.json or packageManager indicates npm).","messagePattern":"npm is required to run this project \\(package-lock\\.json or packageManager indicates npm\\)\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/exec.ts","lineNumber":73,"sourceCode":"  const npm = await utilityInstalled(\"npm\")\n  const pnpm = await utilityInstalled(\"pnpm\")\n\n  // Use the plugin's lockfile/packageManager when available, otherwise default to yarn.\n  if (preferred === \"pnpm\") {\n    if (!pnpm) {\n      throw new Error(\n        \"pnpm is required to run this project (pnpm-lock.yaml or packageManager indicates pnpm).\"\n      )\n    }\n    const pnpmCmd =\n      command === \"install\" ? \"pnpm install\" : `pnpm run ${command}`\n    await exec(pnpmCmd, dir)\n    return\n  }\n\n  if (preferred === \"npm\") {\n    if (!npm) {\n      throw new Error(\n        \"npm is required to run this project (package-lock.json or packageManager indicates npm).\"\n      )\n    }\n    const npmCmd =\n      command === \"install\" ? `npm ${command}` : `npm run ${command}`\n    await exec(npmCmd, dir)\n    return\n  }\n\n  // If the project indicates yarn, use it (with npm fallback).\n  if (preferred === \"yarn\") {\n    if (yarn) {\n      await exec(`yarn ${command} --ignore-engines`, dir)\n      return\n    }\n    if (!npm) {\n      throw new Error(\n        \"yarn is required to run this project (yarn.lock or packageManager indicates yarn).\"","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/cli/src/exec.ts#L55-L91","documentation":"runPkgCommand detects the package manager from the plugin project's `packageManager` field or lockfile. If detection resolves to npm (package-lock.json present or packageManager starts with \"npm@\") but the npm binary is not available on PATH, it throws this error rather than substituting another package manager.","triggerScenarios":"Running budi plugin commands (init/build/watch/migrateSvelte5 -> runPkgCommand) in a directory with package-lock.json or \"packageManager\": \"npm@...\" while `npm --version` fails (npm not installed, PATH broken, or running inside a minimal container without Node/npm).","commonSituations":"Minimal Docker/CI images with node but npm removed; corrupted Node installation; running budi via a wrapper that strips PATH; plugin repo converted to npm but toolchain not updated.","solutions":["Install Node.js/npm (or repair the installation) and confirm `npm --version` works","Fix PATH so the node/npm binaries directory is included in the shell/CI environment","Alternatively switch the project's detection signals (remove package-lock.json, change packageManager) to a manager that is installed","Use nvm or a Node docker image that bundles npm"],"exampleFix":"// CI before\n- run: budi plugins build   # npm missing in image\n// after\n- uses: actions/setup-node@v4\n  with: { node-version: 20 }\n- run: budi plugins build","handlingStrategy":"validation","validationCode":"const { execSync } = require(\"child_process\")\nconst fs = require(\"fs\")\nfunction assertNpmAvailable(dir = \".\") {\n  const pkg = JSON.parse(fs.readFileSync(dir + \"/package.json\", \"utf8\"))\n  const wantsNpm = fs.existsSync(dir + \"/package-lock.json\") ||\n    (pkg.packageManager || \"\").startsWith(\"npm@\")\n  if (wantsNpm) execSync(\"npm --version\", { stdio: \"ignore\" }) // throws if missing\n}","typeGuard":null,"tryCatchPattern":"try {\n  await runPkgCommand(\"build\", dir)\n} catch (err) {\n  if ((err as Error).message.startsWith(\"npm is required\")) {\n    console.error(\"Install Node.js/npm or fix PATH before building\")\n  }\n  throw err\n}","preventionTips":["Install Node.js (bundles npm) and verify `npm --version` before running budi commands","In CI, use a setup-node step before plugin builds","Don't strip PATH in sudo/containers where the CLI runs","Keep package-lock.json only if npm is the intended manager"],"tags":["cli","plugins","npm","package-manager","environment"],"backgroundTag":"missing-package-manager","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}