Is "netlify build" locally supposed to run identically to "netlify build" remote?

I’ve currently got a project that I am building locally with success, but when I trigger the build on Netlify, it fails. My understanding is that configuration for the project happens in both the netlify.toml file as well as Environment Variables. I’ve confirmed that my Environment Variables are identical in both environments. I’ve confirmed that the Netlify remote build is using my latest code changes.

What additional debugging steps can I take to determine why I’m not experiencing parity in the two builds?

Here is the build log on Netlify:

8:45:57 AM: buildbot version: 742cd4f739071a396139ba5020a96a927941b57d
8:45:57 AM: Fetching cached dependencies
8:45:57 AM: Failed to fetch cache, continuing with build
8:45:57 AM: Starting to prepare the repo for build
8:45:58 AM: No cached dependencies found. Cloning fresh repo
8:45:58 AM: git clone --filter=blob:none https://github.com/crdschurch/crds-unified
8:45:58 AM: Preparing Git Reference pull/1348/head
8:46:00 AM: Custom build command detected. Proceeding with the specified command: "./bin/build.sh"
8:46:01 AM: Starting to install dependencies
8:46:01 AM: Python version set to 3.8
8:46:01 AM: Attempting Ruby version 2.7.2, read from environment
8:46:01 AM: Using Ruby version 2.7.2
8:46:02 AM: Started restoring cached go cache
8:46:02 AM: Finished restoring cached go cache
8:46:03 AM: go version go1.19.13 linux/amd64
8:46:04 AM: Using PHP version 8.0
8:46:05 AM: Attempting Node.js version "16" from .nvmrc
8:46:05 AM: Downloading and installing node v16.20.2...
8:46:05 AM: Downloading https://nodejs.org/dist/v16.20.2/node-v16.20.2-linux-x64.tar.xz...
8:46:05 AM: Computing checksum with sha256sum
8:46:06 AM: Checksums matched!
8:46:08 AM: Now using node v16.20.2 (npm v8.19.4)
8:46:08 AM: Enabling Node.js Corepack
8:46:08 AM: Started restoring cached build plugins
8:46:08 AM: Finished restoring cached build plugins
8:46:08 AM: Started restoring cached corepack dependencies
8:46:08 AM: Finished restoring cached corepack dependencies
8:46:08 AM: Started restoring cached yarn cache
8:46:08 AM: Finished restoring cached yarn cache
8:46:08 AM: No yarn workspaces detected
8:46:08 AM: Started restoring cached node modules
8:46:08 AM: Finished restoring cached node modules
8:46:08 AM: Installing npm packages using Yarn version 1.22.19
8:46:09 AM: yarn install v1.22.19
8:46:09 AM: [1/4] Resolving packages...
8:46:09 AM: [2/4] Fetching packages...
8:46:33 AM: [3/4] Linking dependencies...
8:46:33 AM: warning "apollo-link-context > apollo-link@1.2.14" has incorrect peer dependency "graphql@^0.11.3 || ^0.12.3 || ^0.13.0 || ^14.0.0 || ^15.0.0".
8:46:33 AM: warning "apollo-link-context > apollo-link > apollo-utilities@1.3.4" has incorrect peer dependency "graphql@^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0".
8:46:33 AM: warning " > react-markdown@8.0.7" has unmet peer dependency "@types/react@>=16".
8:46:33 AM: warning "react-outside-click-handler > airbnb-prop-types@2.16.0" has incorrect peer dependency "react@^0.14 || ^15.0.0 || ^16.0.0-alpha".
8:46:33 AM: warning " > styled-components@5.3.11" has unmet peer dependency "react-is@>= 16.8.0".
8:46:33 AM: warning "@storybook/nextjs > css-loader@6.8.1" has unmet peer dependency "webpack@^5.0.0".
8:46:33 AM: warning "@storybook/nextjs > node-polyfill-webpack-plugin@2.0.1" has unmet peer dependency "webpack@>=5".
8:46:33 AM: warning "@storybook/nextjs > postcss-loader@7.3.3" has unmet peer dependency "webpack@^5.0.0".
8:46:33 AM: warning "@storybook/nextjs > sass-loader@12.6.0" has unmet peer dependency "webpack@^5.0.0".
8:46:33 AM: warning "@storybook/nextjs > style-loader@3.3.3" has unmet peer dependency "webpack@^5.0.0".
8:46:33 AM: warning "@storybook/nextjs > @storybook/builder-webpack5 > fork-ts-checker-webpack-plugin@8.0.0" has unmet peer dependency "typescript@>3.6.0".
8:46:33 AM: warning "@storybook/nextjs > @storybook/preset-react-webpack > @storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0" has unmet peer dependency "typescript@>= 4.x".
8:46:33 AM: warning "@storybook/nextjs > @storybook/preset-react-webpack > @storybook/react-docgen-typescript-plugin > react-docgen-typescript@2.2.2" has unmet peer dependency "typescript@>= 4.3.x".
8:46:33 AM: warning " > babel-loader@8.3.0" has unmet peer dependency "webpack@>=2".
8:46:33 AM: warning "eslint-config-next > @typescript-eslint/parser > @typescript-eslint/typescript-estree > tsutils@3.21.0" has unmet peer dependency "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta".
8:46:58 AM: [4/4] Building fresh packages...
8:47:03 AM: Done in 54.72s.
8:47:03 AM: npm packages installed using Yarn
8:47:04 AM: Successfully installed dependencies
8:47:04 AM: Starting build script
8:47:05 AM: Detected 1 framework(s)
8:47:05 AM: "next" at version "13.5.6"
8:47:05 AM: Section completed: initializing
8:47:06 AM: ​
8:47:06 AM: Netlify Build                                                 
8:47:06 AM: ────────────────────────────────────────────────────────────────
8:47:06 AM: ​
8:47:06 AM: ❯ Version
8:47:06 AM:   @netlify/build 29.36.0
8:47:06 AM: ​
8:47:06 AM: ❯ Flags
8:47:06 AM:   baseRelDir: true
8:47:06 AM:   buildId: 65d8bda8c0351b0007c80220
8:47:06 AM:   deployId: 65d8bda8c0351b0007c80222
8:47:06 AM: ​
8:47:06 AM: ❯ Current directory
8:47:06 AM:   /opt/build/repo
8:47:06 AM: ​
8:47:06 AM: ❯ Config file
8:47:06 AM:   /opt/build/repo/netlify.toml
8:47:06 AM: ​
8:47:06 AM: ❯ Context
8:47:06 AM:   deploy-preview
8:47:06 AM: ​
8:47:06 AM: ❯ Warning: Starting January 30, 2024 plugin "@netlify/plugin-nextjs" will be executed with Node.js version 20.
8:47:06 AM:   We"re upgrading our system node version on that day, which means the plugin cannot be executed with your defined Node.js version 16.20.2.
​
8:47:06 AM:   Please make sure your plugin supports being run on Node.js 20.
8:47:06 AM: ​
8:47:06 AM:   Read more about our minimum required version in our forums announcement
8:47:06 AM: ​
8:47:06 AM: ❯ Warning: Starting January 30, 2024 plugin "./plugins/get_vault_env_vars" will be executed with Node.js version 20.
8:47:06 AM:   We"re upgrading our system node version on that day, which means the plugin cannot be executed with your defined Node.js version 16.20.2.
​
8:47:06 AM:   Please make sure your plugin supports being run on Node.js 20.
8:47:06 AM: ​
8:47:06 AM:   Read more about our minimum required version in our forums announcement
8:47:06 AM: ​
8:47:06 AM: ❯ Warning: Starting January 30, 2024 plugin "@helloample/netlify-plugin-redirects" will be executed with Node.js version 20.
8:47:06 AM:   We"re upgrading our system node version on that day, which means the plugin cannot be executed with your defined Node.js version 16.20.2.
​
8:47:06 AM:   Please make sure your plugin supports being run on Node.js 20.
8:47:06 AM: ​
8:47:06 AM:   Read more about our minimum required version in our forums announcement
8:47:07 AM: ​
8:47:07 AM: ❯ Using Next.js Runtime - v4.41.1
8:47:07 AM: ​
8:47:07 AM: ❯ Loading plugins
8:47:07 AM:    - ./plugins/get_vault_env_vars@0.1.0 from netlify.toml
8:47:07 AM:    - @helloample/netlify-plugin-redirects@1.3.0 from netlify.toml and package.json
8:47:07 AM: ​
8:47:07 AM: ❯ Outdated plugins
8:47:07 AM:    - @netlify/plugin-nextjs@4.41.1: latest version is 4.41.3
8:47:07 AM:      Migration guide: https://ntl.fyi/next-plugin-migration
8:47:07 AM:      To upgrade this plugin, please update its version in "package.json"
8:47:08 AM: ​
8:47:08 AM: @netlify/plugin-nextjs (onPreBuild event)                     
8:47:08 AM: ────────────────────────────────────────────────────────────────
8:47:08 AM: ​
8:47:08 AM: No Next.js cache to restore.
8:47:08 AM: Not running Next Runtime
8:47:08 AM: ​
8:47:08 AM: (@netlify/plugin-nextjs onPreBuild completed in 8ms)
8:47:08 AM: ​
8:47:08 AM: ./plugins/get_vault_env_vars (onPreBuild event)               
8:47:08 AM: ────────────────────────────────────────────────────────────────
8:47:08 AM: ​
8:47:08 AM: Hello world
8:47:08 AM: envVars:  1
8:47:08 AM: fileData:  36
8:47:08 AM: .env rewritten
8:47:08 AM: Vault Vars Successfully Written to vaultEnvVars.txt
8:47:08 AM: ​
8:47:08 AM: (./plugins/get_vault_env_vars onPreBuild completed in 130ms)
8:47:08 AM: ​
8:47:08 AM: build.command from netlify.toml                               
8:47:08 AM: ────────────────────────────────────────────────────────────────
8:47:08 AM: ​
8:47:08 AM: $ ./bin/build.sh
8:47:08 AM: Running storybook build!!!!!!!!!!!!!!!
8:47:08 AM: > crds-unified@0.1.0 build-storybook
8:47:08 AM: > storybook build -o ./.next
8:47:09 AM: @storybook/cli v7.6.10
8:47:09 AM: 
8:47:09 AM: info => Cleaning outputDir: /.next
8:47:10 AM: info => Loading presets
8:47:10 AM: info => Building manager..
8:47:10 AM: WARN unable to find package.json for react-leaflet
8:47:10 AM: ✘ [ERROR] The define key "process.env.0" contains invalid identifier "0"
8:47:10 AM: Error: Build failed with 1 error:
8:47:10 AM: error: The define key "process.env.0" contains invalid identifier "0"
8:47:10 AM:     at failureErrorWithLog (./node_modules/esbuild/lib/main.js:1649:15)
8:47:10 AM:     at ./node_modules/esbuild/lib/main.js:1058:25
8:47:10 AM:     at runOnEndCallbacks (./node_modules/esbuild/lib/main.js:1484:45)
8:47:10 AM:     at buildResponseToResult (./node_modules/esbuild/lib/main.js:1056:7)
8:47:10 AM:     at ./node_modules/esbuild/lib/main.js:1085:16
8:47:10 AM:     at responseCallbacks.<computed> (./node_modules/esbuild/lib/main.js:703:9)
8:47:10 AM:     at handleIncomingPacket (./node_modules/esbuild/lib/main.js:762:9)
8:47:10 AM:     at Socket.readFromStdout (./node_modules/esbuild/lib/main.js:679:7)
8:47:10 AM:     at Socket.emit (node:events:513:28)
8:47:10 AM:     at addChunk (node:internal/streams/readable:315:12)
8:47:10 AM: attention => Storybook now collects completely anonymous telemetry regarding usage.
8:47:10 AM: This information is used to shape Storybook"s roadmap and prioritize features.
You can learn more, including how to opt-out if you"d not like to participate in this anonymous program, by visiting the following URL:
https://storybook.js.org/telemetry
8:47:10 AM: ​
8:47:10 AM: "build.command" failed                                        
8:47:10 AM: ────────────────────────────────────────────────────────────────
8:47:10 AM: ​
8:47:10 AM:   Error message
8:47:10 AM:   Command failed with exit code 1: ./bin/build.sh (https://ntl.fyi/exit-code-1)
8:47:10 AM: ​
8:47:10 AM:   Error location
8:47:10 AM:   In build.command from netlify.toml:
8:47:10 AM:   ./bin/build.sh
8:47:10 AM: ​
8:47:10 AM:   Resolved config
8:47:10 AM:   build:
8:47:10 AM:     command: ./bin/build.sh
8:47:10 AM:     commandOrigin: config
8:47:10 AM:     environment:
8:47:10 AM:       - JWT_SECRET
8:47:10 AM:       - NETLIFY_NEXT_PLUGIN_SKIP
8:47:10 AM:       - REVIEW_ID
8:47:10 AM:       - STORYBOOK_BUILD
8:47:10 AM:       - STORYBOOK_CONTENTFUL_ACCESS_TOKEN
8:47:10 AM:       - STORYBOOK_CONTENTFUL_ENV
8:47:10 AM:       - STORYBOOK_CONTENTFUL_PREVIEW_TOKEN
8:47:10 AM:       - STORYBOOK_CONTENTFUL_SPACE_ID
8:47:10 AM:       - STORYBOOK_CRDS_INTERACTIONS_ENDPOINT
8:47:10 AM:       - VAULT_ENV
8:47:10 AM:       - VAULT_ROLE_ID
8:47:10 AM:       - VAULT_SECRET_FOLDER
8:47:10 AM:       - VAULT_SECRET_ID
8:47:10 AM:     publish: /opt/build/repo/.next
8:47:10 AM:     publishOrigin: config
8:47:10 AM:   functions:
8:47:10 AM:     refreshInstagramToken:
8:47:10 AM:       schedule: "@monthly"
8:47:10 AM:   functionsDirectory: /opt/build/repo/netlify/functions
8:47:10 AM:   plugins:
8:47:10 AM:     - inputs: {}
8:47:10 AM:       origin: config
8:47:10 AM:       package: "@netlify/plugin-nextjs"
8:47:10 AM:     - inputs: {}
8:47:10 AM:       origin: config
8:47:10 AM:       package: ./plugins/get_vault_env_vars
8:47:10 AM:     - inputs: {}
8:47:10 AM:       origin: config
8:47:10 AM:       package: "@helloample/netlify-plugin-redirects"
8:47:11 AM: Build failed due to a user error: Build script returned non-zero exit code: 2
8:47:11 AM: Failing build: Failed to build site
8:47:11 AM: Finished processing build request in 1m14.018s
8:47:11 AM: Failed during stage "building site": Build script returned non-zero exit code: 2

Here is my local build log:

Netlify Build
────────────────────────────────────────────────────────────────
​
❯ Version
  @netlify/build 29.36.1
​
❯ Flags
  dry: false
  offline: false
​
❯ Current directory
  /home/mjvezzani/work/crossroads/crds-unified
​
❯ Config file
  /home/mjvezzani/work/crossroads/crds-unified/netlify.toml
​
❯ Context
  production
​
❯ Using Next.js Runtime - v4.41.1
​
❯ Loading plugins
   - ./plugins/get_vault_env_vars@0.1.0 from netlify.toml
   - @helloample/netlify-plugin-redirects@1.3.0 from netlify.toml and package.json
​
❯ Outdated plugins
   - @netlify/plugin-nextjs@4.41.1: latest version is 4.41.3
     Migration guide: https://ntl.fyi/next-plugin-migration
     To upgrade this plugin, please update its version in "package.json"
​
@netlify/plugin-nextjs (onPreBuild event)
────────────────────────────────────────────────────────────────
​
No Next.js cache to restore.
Not running Next Runtime
​
(@netlify/plugin-nextjs onPreBuild completed in 9ms)
​
./plugins/get_vault_env_vars (onPreBuild event)
────────────────────────────────────────────────────────────────
​
Hello world
envVars:  28
fileData:  1720
.env truncated
.env rewritten
​
(./plugins/get_vault_env_vars onPreBuild completed in 1.1s)
​
build.command from netlify.toml
────────────────────────────────────────────────────────────────
​
$ ./bin/build.sh
Running storybook build!!!!!!!!!!!!!!!

> crds-unified@0.1.0 build-storybook
> storybook build -o ./.next

@storybook/cli v7.6.10

info => Cleaning outputDir: /.next
info => Loading presets
info => Building manager..
WARN unable to find package.json for react-leaflet
info => Manager built (245 ms)
info => Building preview..
info => Copying static files: /home/mjvezzani/work/crossroads/crds-unified/node_modules/@storybook/manager/static at /home/mjvezzani/work/crossroads/crds-unified/.next/sb-common-assets
info Using Babel compiler
info Addon-docs: using MDX2
info => Using implicit CSS loaders
info => Using default Webpack5 setup
10% building 0/1 entries 1/1 dependencies 0/1 modulesinfo => Copying static files: /home/mjvezzani/work/crossroads/crds-unified/public at /home/mjvezzani/work/crossroads/crds-unified/.next/
WARN asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
WARN This can impact web performance.
WARN Assets:
WARN   static/media/annual-report-header.d11cf15e.jpg (762 KiB)
WARN   3426.c16de607.iframe.bundle.js (583 KiB)
WARN   8773.ce5b294e.iframe.bundle.js (246 KiB)
WARN   5376.84f9ab12.iframe.bundle.js (263 KiB)
WARN   4465.73bb2296.iframe.bundle.js (976 KiB)
WARN   269.41f2236c.iframe.bundle.js (699 KiB)
WARN entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance.
WARN Entrypoints:
WARN   main (1.03 MiB)
WARN       runtime~main.134da1c2.iframe.bundle.js
WARN       4465.73bb2296.iframe.bundle.js
WARN       main.eadcdf8a.iframe.bundle.js
WARN
info => Preview built (31 s)
info => Output directory: /home/mjvezzani/work/crossroads/crds-unified/.next
​
(build.command completed in 34.1s)
​
@netlify/plugin-nextjs (onBuild event)
────────────────────────────────────────────────────────────────
​
​
(@netlify/plugin-nextjs onBuild completed in 5ms)
​
@helloample/netlify-plugin-redirects (onBuild event)
────────────────────────────────────────────────────────────────
​
Wrote 2630 redirect rules to ./.next/_redirects.
​
(@helloample/netlify-plugin-redirects onBuild completed in 2.2s)
​
Functions bundling
────────────────────────────────────────────────────────────────
​
Packaging Functions from netlify/functions directory:
 - add-happenings-background.js
 - jwt-generator.js
 - refreshInstagramToken.js
​
​
(Functions bundling completed in 1.5s)
​
@netlify/plugin-nextjs (onPostBuild event)
────────────────────────────────────────────────────────────────
​
No Next.js cache to save.
​
(@netlify/plugin-nextjs onPostBuild completed in 40ms)
​
Save updated config
────────────────────────────────────────────────────────────────
​
​
(options.onEnd completed in 58ms)
​
Summary
────────────────────────────────────────────────────────────────
​
❯ @netlify/plugin-nextjs: Next Runtime did not run
  Next cache was stored, but all other functions were skipped because NETLIFY_NEXT_PLUGIN_SKIP is set
​
❯ @helloample/netlify-plugin-redirects: Redirects processed successfully
  Wrote 2630 redirect rules to ./.next/_redirects.

Do you have an environment variable named 0 somewhere? Could you share a reproduction where we can see what’s happening? The error message in itself doesn’t seem to be a Netlify issue, but an esbuild issue (from the stacktrace as well as this GitHub issue: define cannot be used with indexed accessors · Issue #2050 · evanw/esbuild (github.com))