11 days ago
Build failure — handover note
Summary
Next.js 15 app on Railway. Build fails at the CSS step with Error: Cannot find module 'autoprefixer', imported from ./src/app/globals.css.
The repository was uploaded through GitHub's web drag-and-drop, so there is no package-lock.json and the person maintaining it has no terminal access.
Environment
Railway, Nixpacks builder, EU West
Repo is nested: Railway Root Directory is set to stakeholder-platform
Build command npm i then npm run build
Services: this app + Railway Postgres
What has been tried
Tailwind v4 originally. Failed with Cannot find native binding from @tailwindcss/oxide — the known npm optional-dependency bug (npm/cli#4828).
Added @tailwindcss/oxide-linux-x64-gnu explicitly. No change.
Downgraded to Tailwind v3 (pure JS, no native binary):
postcss.config.mjs → { plugins: { tailwindcss: {} } }
added tailwind.config.ts with the brand palette
globals.css → @tailwind base/components/utilities + CSS variables
package.json → tailwindcss@^3.4.17, postcss, autoprefixer
Moved tailwindcss, postcss, autoprefixer from devDependencies into dependencies, since Railway builds with NODE_ENV=production and skips dev dependencies.
The blocking symptom
npm i reports added 158 packages on every build, unchanged across the last three deploys, including after package.json was edited. Earlier it changed (103 → 158), so commits have reached the builder at least once.
158 is far too few for this dependency set — Next 15 + React 19 + Drizzle + Tailwind should be several hundred. This suggests the build is not using the package.json currently in the repository.
Decisive evidence (added after further testing)
Two facts together suggest the build is not seeing the repository files as GitHub displays them:
postcss.config.mjs was reduced to export default { plugins: {} }; and all @tailwind directives were removed from globals.css. The build still fails with Cannot find module 'autoprefixer', which should be impossible if Next were reading that config — with no plugins configured, nothing should be resolved at all. Next appears to be falling back to its default PostCSS configuration, i.e. it is not picking up the file.
npm i reports exactly added 158 packages on every build, unchanged across at least six deploys, several different package.json versions, and a Node 18 → Node 20 switch via NIXPACKS_NODE_VERSION. The Node change did take effect (visible in the Nixpacks header), so variables reach the build while file contents appear not to.
Commit SHAs do advance between deploys (d36d972f → 0ec2b575), so the service is not pinned to one commit.
Worth checking first
Is there a second PostCSS config (postcss.config.js alongside postcss.config.mjs)? Next may be preferring one over the other.
Does stakeholder-platform/package.json in the built commit actually contain tailwindcss / autoprefixer / postcss under dependencies?
Does clearing the Railway build cache change the added N packages figure?
Most likely causes, in order
A second package.json in the repo — one being edited, a different one being built. Worth checking for duplicates first.
Root Directory / build context mismatch — Railway resolving package.json from a different path than expected.
Stale build cache — the log mounts --mount=type=cache,target=/app/node_modules/.cache. Clearing the build cache and redeploying would rule this out.
What would settle it in one command
git clone && cd stakeholder-platform
npm install && npm run build
If it builds locally, the problem is Railway's build context, not the code. If it fails locally, the error will name the file directly.
Other context
The application code has never been compiled — it was written in an environment without npm registry access. Type errors are likely and next.config.ts currently sets typescript.ignoreBuildErrors: true as a temporary measure. That should be removed once the type errors are fixed.
The identity-resolution logic in src/lib/identity.ts is tested and passing — 13 unit tests, runnable with node --experimental-strip-types --test tests/identity.test.ts, no install required.
Once the build passes, remaining steps are: set the start command to npm run setup (creates tables and seeds), then revert it to npm run start, then generate a public domain. See docs/RAILWAY-DEPLOY.md.
6 Replies
11 days ago
This thread has been opened as a bounty so the community can help solve it.
Status changed to Open Railway • 11 days ago
11 days ago
Try migrating to a custom Railpack or Dockerfile build. Nixpacks is deprecated.
11 days ago
Thanks
re. Railpack The builder is set to Railpack, but every build log shows using build driver nixpacks-v1.41.0. A Custom Build Command set in Settings also never appears in the build — the log still shows the default npm run build. Environment variables do apply (setting NIXPACKS_NODE_VERSION=20 changed the build to Node 20). It looks like service settings aren't reaching the builder.
11 days ago
I have additional feedback re. the Docker file but need to send privately if you have an inbox
conroyan
Thanks re. Railpack The builder is set to Railpack, but every build log shows using build driver nixpacks-v1.41.0. A Custom Build Command set in Settings also never appears in the build — the log still shows the default npm run build. Environment variables do apply (setting NIXPACKS_NODE_VERSION=20 changed the build to Node 20). It looks like service settings aren't reaching the builder.
11 days ago
Do you have a railway.json or toml file somewhere in the repository? That might be overriding the settings.
11 days ago
yes have railway.json
11 days ago
Service settings and repository changes are not reaching the builder.
Builder is set to Railpack, but every build log shows using build driver nixpacks-v1.41.0.
A Dockerfile was committed to the service's root directory (stakeholder-platform/Dockerfile). It is not being used — the build still runs the Nixpacks default npm i / npm run build.
A Custom Build Command set in Settings never appears in the build either.
npm i reports added 158 packages on every build, unchanged across ~8 deploys and several different package.json files.
Logs show fetched snapshot sha256:da10991009820fa338886b372a7a4fd22c487ed405027909229465f7c30c3dfe (47 kB) — the same snapshot appears to be reused rather than the latest commit being fetched.
Environment variables do apply — setting NIXPACKS_NODE_VERSION=20 changed the build from Node 18 to Node 20.
A railway.json committed to the service root with "builder": "DOCKERFILE" is also ignored — the build still reports using build driver nixpacks-v1.41.0. Dockerfile, railway.json and package.json changes are all being disregarded; only environment variables take effect.