Source files not found while running github jobs

I am using sendgrid’s node js api to send email via a contact form on the site. The form works (sends successfully) when running it on localhost but not on the github preview-deploys. It seems that it can’t find two critical api’s in pages/api/ .... so the form seems to send (the api call sends a 200 but sendgrid does not send the 202 response) but never actually gets sent. Build log and package.json below.

──────────────────────────────────────────────────────────────
  Netlify Build                                                 
────────────────────────────────────────────────────────────────
​
❯ Version
  @netlify/build 28.0.1
​
❯ Flags
  {}
​
❯ Current directory
  /home/runner/work/equity-tool/equity-tool
​
❯ Config file
  /home/runner/work/equity-tool/equity-tool/netlify.toml
​
❯ Context
  production
​
❯ Using Next.js Runtime - v4.28.3
​
❯ Outdated plugins
   - @netlify/plugin-nextjs@4.28.3: latest version is 4.28.4
     Migration guide: https://ntl.fyi/next-plugin-migration
     To upgrade this plugin, please update its version in "package.json"
​
────────────────────────────────────────────────────────────────
  1. @netlify/plugin-nextjs (onPreBuild event)                  
────────────────────────────────────────────────────────────────
​
No Next.js cache to restore.
Netlify configuration property "build.environment.NEXT_PRIVATE_TARGET" value changed.
​
(@netlify/plugin-nextjs onPreBuild completed in 160ms)
​
────────────────────────────────────────────────────────────────
  2. build.command from netlify.toml                            
────────────────────────────────────────────────────────────────
​
$ npm run build

> equity-tool@0.1.17 build
> next build


info  - Creating an optimized production build...
info  - Disabled SWC as replacement for Babel because of custom Babel configuration ".babelrc" https://nextjs.org/docs/messages/swc-disabled
info  - Using external babel configuration from /home/runner/work/equity-tool/equity-tool/.babelrc
info  - Compiled successfully
info  - Collecting page data...
info  - Generating static pages (0/1532)
info  - Generating static pages (299/1532)
info  - Generating static pages (383/1532)
info  - Generating static pages (544/1532)
info  - Generating static pages (759/1532)
info  - Generating static pages (766/1532)
info  - Generating static pages (1149/1532)
info  - Generating static pages (1518/1532)
info  - Generating static pages (1532/1532)
info  - Finalizing page optimization...

Route (pages)                                                    Size     First Load JS
┌   /_app                                                        0 B             234 kB
├ λ /404                                                         2.09 kB         236 kB
├ ○ /about                                                       6.47 kB         241 kB
├ λ /api/feedback                                                0 B             234 kB
├ λ /api/health                                                  0 B             234 kB
├ ○ /contact                                                     38.9 kB         273 kB
├ ● /data/[geography]/[geoid]/[category]/[subgroup] (320014 ms)  5.84 kB         288 kB
├   ├ /data/district/3809/hsaq/tot (1248 ms)
├   ├ /data/district/4011/econ/wnh (640 ms)
├   ├ /data/district/3708/econ/anh (534 ms)
├   ├ /data/citywide/nyc/econ/bnh (533 ms)
├   ├ /data/district/3706/econ/bnh (532 ms)
├   ├ /data/district/4015/econ/bnh (531 ms)
├   ├ /data/district/4008/econ/anh (526 ms)
├   └ [+1518 more paths]
├ ● /map/[view]/[geography]                                      621 kB          903 kB
├   ├ /map/data/district
├   ├ /map/data/borough
├   ├ /map/data/citywide
├   └ /map/drm/nta
└ ○ /methods                                                     8.09 kB         242 kB
+ First Load JS shared by all                                    234 kB
  ├ chunks/framework-3fe34326565e0106.js                         45.3 kB
  ├ chunks/main-2a654e2f3d111e90.js                              29.8 kB
  ├ chunks/pages/_app-96b81a5eb7f059e4.js                        157 kB
  └ chunks/webpack-7e1ede0247721957.js                           1.99 kB

λ  (Server)  server-side renders at runtime (uses getInitialProps or getServerSideProps)
○  (Static)  automatically rendered as static HTML (uses no initial props)
●  (SSG)     automatically generated as static HTML + JSON (uses getStaticProps)

(build.command completed in 6m 52.7s)
────────────────────────────────────────────────────────────────
  3. @netlify/plugin-nextjs (onBuild event)                     
────────────────────────────────────────────────────────────────

/* ***************** this block ************************ */
Could not find source file for page /api/feedback
Could not find source file for page /api/health
/* ***************************************************** */
{
  functionsDir: '/home/runner/work/equity-tool/equity-tool/.netlify/functions-internal'
}
Patching /home/runner/work/equity-tool/equity-tool/node_modules/next/dist/server/base-server.js
Done
Patching /home/runner/work/equity-tool/equity-tool/node_modules/next/dist/server/next-server.js
Done
Moving static page files to serve from CDN...
Moved 2573 files
Using Netlify Edge Functions for image format detection. Set env var "NEXT_DISABLE_EDGE_IMAGES=true" to disable.
Netlify configuration property "redirects" value changed to [
  {
    from: '/',
    query: {},
    to: '/map/data/district',
    force: false,
    conditions: {},
    headers: {}
  },
  {
    from: '/map',
    query: {},
    to: '/map/data/district',
    force: false,
    conditions: {},
    headers: {}
  },
  {
    from: '/map/data',
    query: {},
    to: '/map/data/district',
    force: false,
    conditions: {},
    headers: {}
  },
  {
    from: '/map/drm',
    query: {},
    to: '/map/drm/nta',
    force: false,
    conditions: {},
    headers: {}
  },
  { from: '/_next/static/*', to: '/static/:splat', status: 200 },
  {
    from: '/_next/image*',
    query: { url: ':url', w: ':width', q: ':quality' },
    to: '/_ipx/w_:width,q_:quality/:url',
    status: 301
  },
  { from: '/_ipx/*', to: '/.netlify/builders/_ipx', status: 200 },
  { from: '/cache/*', to: '/404.html', status: 404, force: true },
  { from: '/server/*', to: '/404.html', status: 404, force: true },
  { from: '/serverless/*', to: '/404.html', status: 404, force: true },
  { from: '/trace', to: '/404.html', status: 404, force: true },
  { from: '/traces', to: '/404.html', status: 404, force: true },
  {
    from: '/routes-manifest.json',
    to: '/404.html',
    status: 404,
    force: true
  },
  {
    from: '/build-manifest.json',
    to: '/404.html',
    status: 404,
    force: true
  },
  {
    from: '/prerender-manifest.json',
    to: '/404.html',
    status: 404,
    force: true
  },
  {
    from: '/react-loadable-manifest.json',
    to: '/404.html',
    status: 404,
    force: true
  },
  { from: '/BUILD_ID', to: '/404.html', status: 404, force: true },
  {
    from: '/api/feedback',
    to: '/.netlify/functions/_api_feedback-handler',
    status: 200
  },
  {
    from: '/api/health',
    to: '/.netlify/functions/_api_health-handler',
    status: 200
  },
  {
    from: '/api/*',
    to: '/.netlify/functions/___netlify-handler',
    status: 200
  },
]
​
(@netlify/plugin-nextjs onBuild completed in 1.4s)

package.json

 "engines": {
    "node": ">=16.13.0"
  },
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next build && next start",
    "lint": "run-s lint:tsc lint:eslint",
    "lint:eslint": "eslint '**/*.{js,jsx,ts,tsx}' '*.js'",
    "lint:tsc": "tsc --noEmit && tsc --noEmit --project ./cypress/tsconfig.json",
    "test": "jest -c test/jest.config.js",
    "e2e:open": "cypress open",
    "e2e:run": "cypress run --config video=false",
    "e2e:test": "start-server-and-test start http://localhost e2e:run",
    "ci:test-build": "run-s lint test build e2e:test",
    "prepare": "husky install"
  },
  "dependencies": {
    "@chakra-ui/icons": "^2.0.10",
    "@chakra-ui/react": "^2.3.4",
    "@chakra-ui/theme-tools": "^2.0.11",
    "@danmarshall/deckgl-typings": "^4.9.10",
    "@deck.gl/extensions": "^8.6.8",
    "@emotion/react": "^11.10.4",
    "@emotion/styled": "^11.10.4",
    "@fortawesome/fontawesome-svg-core": "^6.2.0",
    "@fortawesome/free-solid-svg-icons": "^6.2.0",
    "@fortawesome/react-fontawesome": "^0.2.0",
    "@netlify/plugin-nextjs": "^4.28.3",
    "@hookform/resolvers": "^2.9.10",
    "@react-hook/window-size": "^3.1.1",
    "@sendgrid/mail": "^7.7.0",
    "@sentry/nextjs": "^6.18.2",
    "@types/d3-color": "^3.0.2",
    "@types/d3-interpolate": "^3.0.1",
    "@types/d3-scale": "^4.0.2",
    "axios": "^0.26.1",
    "d3-color": "^3.0.1",
    "d3-interpolate": "^3.0.1",
    "d3-scale": "^4.0.2",
    "deck.gl": "^8.6.4",
    "framer-motion": "^7.4.0",
    "next": "^12.3.1",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-ga4": "^1.4.1",
    "react-hook-form": "^7.38.0",
    "react-icons": "^4.4.0",
    "react-map-gl": "^6.1.17",
    "yup": "^0.32.11"
  },
  "devDependencies": {
    "@babel/core": "^7.19.3",
    "@babel/preset-env": "^7.19.3",
    "@babel/preset-typescript": "^7.18.6",
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^14.4.3",
    "@types/jest": "^29.0.3",
    "@types/node": "^18.7.23",
    "@types/react": "^18.0.21",
    "@types/react-dom": "^18.0.6",
    "@typescript-eslint/eslint-plugin": "^5.38.1",
    "@typescript-eslint/parser": "^5.38.1",
    "babel-jest": "^29.1.0",
    "cypress": "^8.7.0",
    "eslint": "7.32.0",
    "eslint-config-next": "12.0.3",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-prettier": "^4.0.0",
    "husky": "^7.0.4",
    "jest": "^29.1.1",
    "jest-environment-jsdom": "^29.1.1",
    "lint-staged": "^11.2.6",
    "npm-run-all": "^4.1.5",
    "prettier": "2.4.1",
    "start-server-and-test": "^1.14.0",
    "typescript": "^4.8.4",
    "webpack": "^5.74.0",
    "webpack-cli": "^4.10.0"
  },
  "lint-staged": {
    "*.{ts,tsx,js}": [
      "bash -c 'npm run lint:tsc'",
      "npm run lint:eslint -- --quiet --fix"
    ]
  }

netlify app:

Halp. Lemme know if y’all need more info or details.

:crossed_fingers:
Thx!

Try using the Next.js Runtime v4.28.4+: GitHub - netlify/next-runtime: The Next.js Runtime allows Next.js to run on Netlify with zero configuration

Turns out the solution was to write the env vars to a .env file in our actions in github workflows:

run |
  echo "SENDGRID_API_KEY=$SENDGRID_API_KEY" >> .env
  echo "FROM_EMAIL=$FROM_EMAIL" >> .env
  echo "TO_EMAIL=$TO_EMAIL" >> .env