Docs menu

Troubleshooting Bun

Common build and runtime errors for Bun apps on Primcloud, with the fix for each.

On this page

Two places to look when a deploy misbehaves:

  • Build log: the Deployments tab streams the full build output. Bun version resolution, bun install, build scripts, and pruning all surface here.
  • Runtime log: the Logs tab streams stdout and stderr from your running pods. Startup crashes, unhandled rejections, and missing-module errors show up here.

This page lists the errors that come up most often, in the order they'd typically bite you: detection, version resolution, install, build scripts, process types, then runtime.

Common build errors#

The app builds as Node.js, not Bun#

The build log shows the Node.js toolchain instead of Bun. Your repo has a package.json but nothing that marks it as a Bun app.

Fix. Commit bun.lock. For an app with no dependencies (which Bun writes no lockfile for), add a .bun-version file, a bunfig.toml, or "packageManager": "bun@<version>" to package.json. See Bun on Primcloud → Detection.

Missing Bun lockfile#

The repo was detected as a Bun app through bunfig.toml, .bun-version, or packageManager, it has dependencies, and no lockfile is committed. Without a lockfile, installed versions can differ from one build to the next, so the build stops.

Fix. Run bun install locally and commit the bun.lock it writes. Check that bun.lock isn't in .gitignore.

Failed to install dependencies#

bun install --frozen-lockfile exited non-zero. Usually the lockfile disagrees with package.json: a manual edit, or a merge that resolved one file and not the other. A private package without registry credentials fails here too.

Fix. Reproduce locally:

Terminal
bun install --frozen-lockfile

If it fails the same way, run bun install, commit the updated lockfile, and redeploy. For private packages, see Package managers → Private packages and registries.

Invalid Bun version#

.bun-version or packageManager holds something other than an exact version: a range (^1.4.0), latest, a partial version (1.4), or a trailing comment. Or engines.bun holds a value that's neither a version nor a semver range.

Fix. Use an exact major.minor.patch version in .bun-version and packageManager. Ranges are only accepted in engines.bun. See Runtime versions.

Unsupported Bun version range#

engines.bun holds a range that Primcloud's default Bun version doesn't satisfy. A range only ever resolves to the default.

Fix. Pin an exact Bun version in engines.bun, packageManager, or .bun-version.

Unknown Bun version#

The pinned version isn't a Bun release, or has no Linux build.

Fix. Pick a version from Bun's releases.

Failed to download Bun distribution#

The build couldn't fetch Bun. Failed requests are retried automatically before the build gives up, so this usually means an upstream outage.

Fix. Redeploy.

Failed to execute build script#

One of heroku-prebuild, heroku-build / build, or heroku-postbuild exited non-zero. The script's own output is directly above the error in the build log.

Fix. Run the script locally from a clean checkout:

Terminal
bun install --frozen-lockfile
bun run build

If it passes locally, the difference is usually an environment variable the script reads (set it in the Secrets panel), or a tool that expects a node binary. See Customizing the build → Tools that expect Node.js.

No process types found#

The build finished, but there's nothing to run: no Procfile, no start script, and no root server.js, index.js, server.ts, or index.ts. The build log notes that no web process was registered.

Fix. Add a start script to package.json, or a Procfile that declares a web process.

Error parsing package.json#

package.json isn't valid JSON.

Fix. Fix the syntax and redeploy. The build log names the position of the parse error.

Common runtime errors#

App doesn't bind to $PORT#

Symptom: the deployment reaches Release Succeeded but the URL returns a connection error.

Fix. Listen on the port Primcloud assigns:

Bun.serve({
  port: Number(process.env.PORT),
  fetch(req) {
    return new Response("ok");
  },
});

Primcloud sets PORT to 5000 on the web formation and routes traffic only there. Hard-coding another port means requests never reach your app.

Cannot find module at runtime#

The app starts and immediately fails importing a package that was present during the build. The package isn't in your lockfile (a build script installed it on the side), and packages the lockfile doesn't list are removed after the build scripts run.

Fix. Add the package to package.json, regenerate the lockfile, and redeploy.

App exits immediately on start#

The runtime log shows the process starting and then exiting.

Most common causes:

  • Wrong entry point. bun run start runs whatever your start script says. Verify it points at a file that exists in the deployed app. If it points into dist/, confirm a build script actually produces it.
  • Missing required env var. Set it in the Secrets panel and redeploy.
  • Code that assumes development. NODE_ENV defaults to production at runtime. If your app needs something else, set NODE_ENV in the Secrets panel.

Debugging tips#

  • Reproduce the install locally. bun install --frozen-lockfile is the exact command the build runs. Most install failures reproduce this way.
  • Check the resolved Bun version. The build log prints the version it detected, where it found it, and the version it resolved. Match it locally before chasing a behavior difference.
  • Pin an exact Bun version. An unpinned app follows Primcloud's default, which moves forward over time.