SvelteKit 2: Builds fail - Cannot read values from $env/dynamic/private while prerendering (attempted to read env.DATABASE_URL). Use $env/static/private instead
Describe the bug
Got my project migrated to SvelteKit 2.0 but am now getting this error at the end of the build process...
vite v5.0.10 building SSR bundle for production...
✓ 302 modules transformed.
vite v5.0.10 building for production...
✓ 978 modules transformed.
Generated an empty chunk: "4".
[plugin:vite:reporter]
(!) /Users/nates/dev/shy-svelte/node_modules/braintree-web/dist/browser/index.js is dynamically imported by /Users/nates/dev/shy-svelte/src/lib/braintree.ts but also statically imported by /Users/nates/dev/shy-svelte/src/lib/braintree.ts, dynamic import will not move module into another chunk.
.svelte-kit/output/client/_app/version.json 0.03 kB │ gzip: 0.05 kB
.svelte-kit/output/client/.vite/manifest.json 23.42 kB │ gzip: 2.26 kB
.svelte-kit/output/client/_app/immutable/assets/27.XxC2WWV9.css 0.03 kB │ gzip: 0.05 kB
.svelte-kit/output/client/_app/immutable/assets/19.FoEC6RxX.css 0.04 kB │ gzip: 0.06 kB
.svelte-kit/output/client/_app/immutable/assets/32.ja80Eq4H.css 0.04 kB │ gzip: 0.06 kB
...
.svelte-kit/output/client/_app/immutable/chunks/Classes.2ARxv3iI.js 57.66 kB │ gzip: 18.48 kB │ map: 101.10 kB
.svelte-kit/output/client/_app/immutable/chunks/CartEditor.rVXpy9rg.js 328.04 kB │ gzip: 84.72 kB │ map: 1,265.90 kB
.svelte-kit/output/client/_app/immutable/nodes/8.xCG6n4wP.js 391.35 kB │ gzip: 111.03 kB │ map: 1,378.48 kB
✓ built in 5.39s
node:internal/event_target:1062
process.nextTick(() => { throw err; });
^
Error: Cannot read values from $env/dynamic/private while prerendering (attempted to read env.DATABASE_URL). Use $env/static/private instead
at Object.get (file:///Users/nates/dev/shy-svelte/.svelte-kit/output/server/index.js:2867:11)
at file:///Users/nates/dev/shy-svelte/.svelte-kit/output/server/chunks/db.js:6:33
at ModuleJob.run (node:internal/modules/esm/module_job:195:25)
at async ModuleLoader.import (node:internal/modules/esm/loader:336:24)
at async Server.init (file:///Users/nates/dev/shy-svelte/.svelte-kit/output/server/index.js:2899:24)
at async prerender (file:///Users/nates/dev/shy-svelte/node_modules/@sveltejs/kit/src/core/postbuild/prerender.js:102:2)
at async MessagePort.<anonymous> (file:///Users/nates/dev/shy-svelte/node_modules/@sveltejs/kit/src/utils/fork.js:22:16)
Emitted 'error' event on Worker instance at:
at [kOnErrorMessage] (node:internal/worker:314:10)
at [kOnMessage] (node:internal/worker:325:37)
at MessagePort.<anonymous> (node:internal/worker:225:57)
at [nodejs.internal.kHybridDispatch] (node:internal/event_target:786:20)
at exports.emitMessage (node:internal/per_context/messageport:23:28)
Node.js v18.19.0
The module that uses this private env value is:
import type { QueryResult } from 'pg'
import pg from 'pg'
import { env } from '$env/dynamic/private'
const pool = new pg.Pool({
max: 10, // default
connectionString: env.DATABASE_URL,
ssl: {
rejectUnauthorized: false
}
})
type PostgresQueryResult = (sql: string, params?: any[]) => Promise<QueryResult<any>>
export const query: PostgresQueryResult = (sql, params?) => pool.query(sql, params)
It is only called by +server.ts files in my routes.3 All pages with load functions have export const prerender = false.
Reproduction
https://stackblitz.com/~/github.com/nstuyvesant/shy-svelte
- Copy the contents of mock-env
- Paste into the .env file StackBlitz creates at the root directory and Save
- In the terminal, run
yarn build
Error will appear.
Logs
See above
System Info
System:
OS: macOS 14.2
CPU: (10) arm64 Apple M1 Pro
Memory: 1.54 GB / 32.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 18.19.0 - /opt/homebrew/bin/node
Yarn: 1.22.19 - /opt/homebrew/bin/yarn
npm: 10.2.5 - /opt/homebrew/bin/npm
pnpm: 7.29.1 - /opt/homebrew/bin/pnpm
Browsers:
Chrome: 120.0.6099.109
Safari: 17.2
npmPackages:
@sveltejs/adapter-node: ^2.0.0 => 2.0.0
@sveltejs/kit: ^2.0.1 => 2.0.1
@sveltejs/vite-plugin-svelte: ^3.0.1 => 3.0.1
svelte: ^4.2.8 => 4.2.8
vite: ^5.0.10 => 5.0.10
Severity
blocking an upgrade
Additional Information
Build only appears to fail on pre-rendering.
The top-level +layout.server.ts (as do almost all pages) has...
export const prerender = false
See: https://github.com/sveltejs/kit/pull/11277#issuecomment-1856504688 https://github.com/sveltejs/kit/issues/11341#issuecomment-1858836699
It does become quite inconvenient to have to prevent any references to it while building, I hope that can be changed.
Thanks again, @CaptainCodeman. Those links confirmed this was an intentional change and your workaround helped me.
My app doesn't do pre-rendering (disabled in +layout.server.ts) and this put me off course. I didn't even consider that the hooks.server.ts because my inaccurate thinking about pre-rendering didn't see hooks as having a role at build time.
Your solution involving import { building } from '$app/environment' then using a ternary where the environmental variable was directly used solved the problem... connectionString: building ? '' : env.DATABASE_URL.
I looked everywhere there might be pre-rendering but not in the hooks. Perhaps the documentation on prerendering could mention the role of hooks even when prerendering is otherwise disabled?
The reproduction doesn't work - it appears github.com/nstuyvesant/shy-svelte has been deleted
https://github.com/sveltejs/kit/pull/11436 was related to improving similar issues. I'm unsure if there's anything left to do here. If folks are still having issues, can someone post a new reproduction?
I should have some projects with workarounds I can revert, to confirm.
Hi @benmccann - sorry - that one was made private but sounds like @CaptainCodeman will share.
If you could make it public again that would speed things up
@benmccann - done!
That repository is completely impossible to build. If you copy .env.example to .env the app is nowhere close to building. And I don't see anything called mock-env in the GitHub repo. Can you update it so that it can be easily run by anyone?
Or if @CaptainCodeman can share an example that would be helpful as well
Is anyone able to provide a minimal reproduction for this issue? If not, I will close it
IMO this works
https://github.com/CaptainCodeman/sk-11371
build & preview shows handle { PUBLIC_TEST: '123' } in the console
(changing import to private shows all the env values set)
Thank you for confirming!