Npm workspaces build with cache fails

I have a build issue with a monorepo application that uses npm workspaces. The initial build succeeds but subsequent builds fail. If I clear cache and build again it succeeds. I’ve included the build log and my netlify.toml at the bottom.

As you can see, the build fails because of a missing dependency (rimraf).

Here’s my abbreviated root package.json:

{
    "private": true,
    "type": "module",
    "workspaces": ["./backend", "./common", "./frontend"],
    ...
}

And here is my abbreviated package.json from the frontend package which is what’s is failing to build:

{
    "private": true,
    "type": "module",
    "scripts": {
        "prebuild": "rimraf dist",
        "build": "parcel build src/index.html src/connector.html"
    },
    "devDependencies": {
        "rimraf": "^3.0.2",
        ...
    },
    ...
}

In the build log there’s No npm workspaces detected even though I’m using npm workspaces. Maybe that’s causing the issue but I have no idea how to get the build image to detect workspaces.

Build log

5:02:44 PM: build-image version: d7b3813f01c06610bc1723ff1b22446513ee7941 (focal)
5:02:44 PM: build-image tag: v4.14.3
5:02:44 PM: buildbot version: 4f669c94b322d52f143cdcbb17e55d40094aa06d
5:02:44 PM: Fetching cached dependencies
5:02:44 PM: Starting to download cache of 129.9MB
5:02:45 PM: Finished downloading cache in 1.098921234s
5:02:45 PM: Starting to extract cache
5:02:46 PM: Finished extracting cache in 769.508784ms
5:02:46 PM: Finished fetching cache in 1.908010772s
5:02:46 PM: Starting to prepare the repo for build
5:02:46 PM: Preparing Git Reference refs/heads/production
5:02:47 PM: Parsing package.json dependencies
5:02:48 PM: Different build dir detected, going to use the one specified in the Netlify configuration file: 'frontend' versus '' in the Netlify UI
5:02:48 PM: Different publish path detected, going to use the one specified in the Netlify configuration file: 'frontend/dist' versus '' in the Netlify UI
5:02:48 PM: Different build command detected, going to use the one specified in the Netlify configuration file: 'npm run build' versus '' in the Netlify UI
5:02:48 PM: Section completed: initializing
5:02:48 PM: Starting build script
5:02:48 PM: Installing dependencies
5:02:48 PM: Python version set to 2.7
5:02:48 PM: Started restoring cached node version
5:02:49 PM: Finished restoring cached node version
5:02:49 PM: Attempting node version 'v18' from .nvmrc
5:02:49 PM: v18.12.1 is already installed.
5:02:50 PM: Now using node v18.12.1 (npm v9.1.2)
5:02:50 PM: Enabling node corepack
5:02:50 PM: Started restoring cached build plugins
5:02:50 PM: Finished restoring cached build plugins
5:02:50 PM: Attempting ruby version 2.7.2, read from environment
5:02:50 PM: Using ruby version 2.7.2
5:02:50 PM: Using PHP version 8.0
5:02:51 PM: No npm workspaces detected
5:02:51 PM: Started restoring cached node modules
5:02:51 PM: Finished restoring cached node modules
5:02:51 PM: Found npm version (9.1.2) that doesn't match expected (9)Installing npm at version 9
5:02:53 PM: changed 15 packages in 1s
5:02:53 PM: 14 packages are looking for funding
5:02:53 PM:   run `npm fund` for details
5:02:53 PM: NPM installed successfully
5:02:53 PM: Started restoring cached go cache
5:02:53 PM: Finished restoring cached go cache
5:02:53 PM: Installing Go version 1.17 (requested 1.17)
5:02:57 PM: unset GOOS;
5:02:57 PM: unset GOARCH;
5:02:57 PM: export GOROOT='/opt/buildhome/.gimme/versions/go1.17.linux.amd64';
5:02:57 PM: export PATH="/opt/buildhome/.gimme/versions/go1.17.linux.amd64/bin:${PATH}";
5:02:57 PM: go version >&2;
5:02:57 PM: export GIMME_ENV="/opt/buildhome/.gimme/env/go1.17.linux.amd64.env"
5:02:57 PM: go version go1.17 linux/amd64
5:02:57 PM: Detected 1 framework(s)
5:02:57 PM: "parcel" at version "0.0.0"
5:02:57 PM: Installing missing commands
5:02:57 PM: Verify run directory
5:02:59 PM: ​
5:02:59 PM: ────────────────────────────────────────────────────────────────
5:02:59 PM:   Netlify Build                                                 
5:02:59 PM: ────────────────────────────────────────────────────────────────
5:02:59 PM: ​
5:02:59 PM: ❯ Version
5:02:59 PM:   @netlify/build 28.1.13
5:02:59 PM: ​
5:02:59 PM: ❯ Flags
5:02:59 PM:   baseRelDir: true
5:02:59 PM:   buildId: 63765b0c6403380008505579
5:02:59 PM:   deployId: 63765b0c640338000850557b
5:02:59 PM: ​
5:02:59 PM: ❯ Current directory
5:02:59 PM:   /opt/build/repo/frontend
5:02:59 PM: ​
5:02:59 PM: ❯ Config file
5:02:59 PM:   /opt/build/repo/netlify.toml
5:02:59 PM: ​
5:02:59 PM: ❯ Context
5:02:59 PM:   production
5:02:59 PM: ​
5:02:59 PM: ────────────────────────────────────────────────────────────────
5:03:00 PM: Creating deploy upload records
5:02:59 PM:   1. build.command from netlify.toml                            
5:02:59 PM: ────────────────────────────────────────────────────────────────
5:02:59 PM: ​
5:02:59 PM: $ npm run build
5:03:00 PM: Failed during stage 'building site': Build script returned non-zero exit code: 2 (https://ntl.fyi/exit-code-2)
5:02:59 PM: > @come/frontend@0.0.0 prebuild
5:02:59 PM: > rimraf dist
5:02:59 PM: sh: 1: rimraf: not found
5:02:59 PM: npm ERR! Lifecycle script `build` failed with error:
5:02:59 PM: npm ERR! Error: command failed
5:02:59 PM: npm ERR!   in workspace: @come/frontend@0.0.0
5:02:59 PM: npm ERR!   at location: /opt/build/repo/frontend
5:02:59 PM: ​
5:02:59 PM: ────────────────────────────────────────────────────────────────
5:02:59 PM:   "build.command" failed                                        
5:02:59 PM: ────────────────────────────────────────────────────────────────
5:02:59 PM: ​
5:02:59 PM:   Error message
5:02:59 PM:   Command failed with exit code 1: npm run build (https://ntl.fyi/exit-code-1)
5:02:59 PM: ​
5:02:59 PM:   Error location
5:02:59 PM:   In build.command from netlify.toml:
5:02:59 PM:   npm run build
5:02:59 PM: ​
5:02:59 PM:   Resolved config
5:02:59 PM:   build:
5:02:59 PM:     base: /opt/build/repo/frontend
5:02:59 PM:     command: npm run build
5:02:59 PM:     commandOrigin: config
5:02:59 PM:     environment:
5:02:59 PM:       - NPM_VERSION
5:02:59 PM:     processing:
5:02:59 PM:       html:
5:02:59 PM:         pretty_urls: true
5:02:59 PM:     publish: /opt/build/repo/frontend/dist
5:02:59 PM:     publishOrigin: config
5:03:00 PM: Caching artifacts
5:03:00 PM: Started saving node modules
5:03:00 PM: Finished saving node modules
5:03:00 PM: Started saving build plugins
5:03:00 PM: Finished saving build plugins
5:03:00 PM: Started saving pip cache
5:03:00 PM: Finished saving pip cache
5:03:00 PM: Started saving emacs cask dependencies
5:03:00 PM: Finished saving emacs cask dependencies
5:03:00 PM: Started saving maven dependencies
5:03:00 PM: Finished saving maven dependencies
5:03:00 PM: Started saving boot dependencies
5:03:00 PM: Finished saving boot dependencies
5:03:00 PM: Started saving rust rustup cache
5:03:00 PM: Finished saving rust rustup cache
5:03:00 PM: Started saving go dependencies
5:03:00 PM: Finished saving go dependencies
5:03:00 PM: Build failed due to a user error: Build script returned non-zero exit code: 2
5:03:00 PM: Failing build: Failed to build site
5:03:00 PM: Finished processing build request in 16.256197687s

netlify.toml

[build]
    base = "frontend"
    command = "npm run build"
    publish = "dist"
    processing = { html = { pretty_urls = true } }

[build.environment]
    NPM_VERSION = "9"

Hey @EmilEriksen,

Our docs show how to work with npm workspaces: Monorepos | Netlify Docs

One thing that stands out is, you’re using relative paths ./, maybe try without that?

Thank you @hrishikesh. That worked! Workspaces are now correctly detected (npm workspaces detected) and the build no longer fails :slight_smile: