I recently encountered a cascade of common roadblocks while bootstrapping, migrating, and seeding a PostgreSQL database using Prisma on Linux. What seemed like a routine script execution quickly turned into a deep troubleshooting session involving module resolution, database permissions, execution engine differences, and migrating the entire project to Bun.
Here is the hands-on breakdown of each bottleneck, the root cause at the OS level, and the final working setup.
1. Initial hurdle: module not found "prisma/seed.ts"#
The issue started when running the standard Prisma database seed command:
error: Module not found "prisma/seed.ts"
Root cause#
When executing prisma db seed, the Prisma CLI checks package.json for the prisma.seed key and spawns a child process to run the configured command.
If the default TypeScript runner (ts-node) attempts to resolve the script path without respecting the current working directory (process.cwd()), the system call (openat/stat) returns ENOENT (No such file or directory).
Additionally, projects configured with ES Modules ("type": "module") or strict tsconfig.json paths break runtime transpilation in older ts-node setups.
Technical fix#
Switching the runner declaration to modern tools or providing explicit paths resolves the issue:
"prisma": {
"seed": "npx tsx ./prisma/seed.ts"
}
2. Setting up PostgreSQL: database creation and permissions#
Before applying migrations, the database role and schema must exist in PostgreSQL. There are two clean approaches:
Using Linux system wrappers#
Ideal for automated shell scripts and provisioning:
# 1. Create role interactively prompting for password
sudo -u postgres createuser --interactive --pwprompt
# 2. Create database with role ownership
sudo -u postgres createdb -O app_user app_db
Using SQL queries (psql)#
For granular permission control (especially on PostgreSQL 15+):
-- Create role with encrypted password
CREATE USER app_user WITH PASSWORD 'your_secure_password';
-- Create database with UTF8 encoding
CREATE DATABASE app_db OWNER app_user;
-- Grant database permissions (on PostgreSQL 15+, database owners already possess full access; for external roles, grant on schema public as well):
GRANT ALL PRIVILEGES ON DATABASE app_db TO app_user;
GRANT ALL ON SCHEMA public TO app_user;
Authentication reminder (pg_hba.conf): Local connections over Unix domain sockets usepeerauthentication by default on Linux (matching OS UID). For TCP/IP (host) or application password authentication,pg_hba.confmust acceptscram-sha-256ormd5, and PostgreSQL must be listening on port 5432 (ss -nltp | grep 5432).
3. Prisma command lifecycle: dev, deploy, and generate#
Once the database is accessible, the Prisma schema lifecycle breaks down into three distinct phases:
- Development with Shadow Database:
npx prisma migrate dev --name init
Creates a temporary shadow database to replay migrations from scratch, verify schema drift, and validate that the resulting database matches schema.prisma.
- Production Deployments:
npx prisma migrate deploy
Applies pending SQL migration files recorded in the _prisma_migrations table without requiring a shadow database.
- Client and Engine Generation:
npx prisma generate
Compiles TypeScript type definitions and copies the Rust-compiled Query Engine binary to node_modules/.prisma/client.
4. Location error: schema.prisma: file not found#
Running the client generation command threw:
set it as `prisma.schema` in your package.json,
or put it into the default location (`./prisma/schema.prisma`, or `./schema.prisma`).
Checked following paths:
schema.prisma: file not found
prisma/schema.prisma: file not found
Prisma checks specific directory paths. If file casing differs (such as Schema.prisma on Linux filesystems) or if the command is executed from a subdirectory, the CLI aborts.
Consolidating the schema inside the standard directory fixed the issue:
mkdir -p prisma && mv schema.prisma prisma/schema.prisma
5. Tool fragmentation: Bun, yarn, and NPM conflicts#
Attempting to run Prisma commands with Bun in the application folder:
bun prisma generate --schema=./prisma/schema.prisma
# Error: Script not found "prisma"
Bun interpreted bun prisma as a request to run an npm script named "prisma" in package.json.
Switching to bunx triggered a missing client dependency error:
Loaded Prisma config from prisma.config.ts.
Prisma schema loaded from prisma/schema.prisma.
Error: Could not resolve @prisma/client.
Please try to install it with yarn install @prisma/client and rerun npx "prisma generate".
Attempting the suggested commands failed immediately:
yarn install @prisma/client
# bash: yarn: command not found
npx prisma generate
# bash: npx: command not found
The host lacked global yarn or npm/npx binaries in $PATH, leaving dependencies out of sync.
6. Architectural decision: standardizing 100% on Bun#
To eliminate tooling bloat and prevent lockfile discrepancies, I standardized the entire stack on Bun and bunx.
Step 1: Cleaning legacy lockfiles and modules#
# Remove NPM and Yarn artifacts
rm -f package-lock.json yarn.lock
rm -rf node_modules
# Clean install generating bun.lock (or bun.lockb on legacy Bun versions)
bun install
# Explicitly install Prisma client
bun add @prisma/client
Step 2: Restructuring package.json#
I removed recursive script aliases and enabled Bun native file watching:
{
"name": "app-project",
"version": "0.1.0",
"private": true,
"scripts": {
"db:generate": "prisma generate --schema=./prisma/schema.prisma",
"db:migrate": "prisma migrate dev --schema=./prisma/schema.prisma",
"db:deploy": "prisma migrate deploy --schema=./prisma/schema.prisma",
"db:seed": "prisma db seed",
"app:dev": "bun --watch src/index.ts",
"app:start": "bun run src/index.ts",
"app:build": "echo 'No build step needed for Bun'"
},
"prisma": {
"seed": "bun prisma/seed.ts"
}
}
7. Final conflict: prisma.config.ts vs package.json#
Running the seed command:
bun run db:seed
# $ prisma db seed
# Loaded Prisma config from prisma.config.ts.
# ⚠️ No seed command configured
# To seed your database, add a seed property to the migrations section in your Prisma config file.
Why did this happen?#
Prisma supports a programmatic prisma.config.ts configuration file. When present, the CLI ignores the "prisma": { "seed": "..." } block in package.json and requires configuration inside the .ts file.
Fix#
Because our runner configuration was already defined in package.json, prisma.config.ts was redundant.
Removing the file resolved the conflict:
rm prisma.config.ts
Prisma fell back to reading package.json, executing bun prisma/seed.ts. Bun ran the TypeScript seed file directly in memory, connected to PostgreSQL, and populated the database without slow Node.js transpilation steps.
Conclusion: operational cheat sheet (Bun runtime)#
For day-to-day operations, the workflow is streamlined:
| Task | Native Bun Command |
|---|---|
| Install dependencies | bun install |
| Generate Prisma Client | bunx prisma generate (or bun run db:generate) |
| Apply Migrations (Prod) | bunx prisma migrate deploy (or bun run db:deploy) |
| Run Seed | bun run db:seed (or directly bun ./prisma/seed.ts) |
| Development Server | bun run app:dev |
Aligning scripts with the correct runtime and removing conflicting configuration files ensures database migrations and seeders execute fast, reliably, and without server overhead.
Was this article helpful?
Leave a quick reaction to help prioritize future technical guides:
This post is licensed under CC BY-NC.



Comments
Join the discussion below.
0 comments