v8.1.1-canary.62 (or maybe 3aed76fad857b518a31675987e8c79f6f1afccde) (re-)introduces an issue with how I use (and recommend how to use) https://github.com/tusbar/next-runtime-dotenv.
This breaks on build as publicRuntimeConfig
is undefined
at build time:
const {
publicRuntimeConfig: {MY_API_URL}
} = getConfig()
publicRuntimeConfig
used to be {}
at build time.
This is not the first time this breaks, maybe it would be nice to add a test. It used to work fine with 8.0.4
, it鈥檚 broken in 8.1.0
and used to work fine in canary before 8.1.1-canary.62
. Broken in 9.0
as well.
@timneutkens could we have a consistent behavior for this? Thanks.
I'm using the built in method of using publicRuntimeConfig and not the above plugin and also receive the same error message on build
@cbarratt the plugin just pre-fills the runtime configuration with environment variables using dotenv
.
Accessing the configuration is not different from the doc.
I also received the same error message on build and think I figured it out why. It has to do with Automatic static optimization introduced in Next 9
, or 8.1.1-canary.62
.
Following the documentation that states "This determination is made by whether or not the page has blocking data requirements through using getInitialProps." I ended up adding getInitialProps to every page in my application and the error went away.
Since there was none getInitialProps statement in some pages, during build it would consider this pages as static and does not expose runtime env configuration.
I'm seeing the same error on build, but am getting notices that Automatic static optimization is opt-out, so not sure if it's related @vitorhsb.
A few details to help debug:
getInitialProps
in _app.js
to renderDataFromTree
. Not sure if that matters. withPlugins
in my next.config.js
file.require("dotenv").config();
in the top of my next.config.js file. (not using next-runtime-dotenv)Compiled successfully.
Warning: You have opted-out of Automatic Prerendering due to `getInitialProps` in `pages/_app`.
Read more: https://err.sh/next.js/opt-out-automatic-prerendering
> Build error occurred
{ TypeError: Cannot read property 'publicRuntimeConfig' of undefined
at Object.ejXW (/Users/egdelwonk/dev/lp/frontend/build/server/static/yNatTl7kpzkSAKqWfkbLL/pages/journals/templates/destination/detail.js:8637:28)
at __webpack_require__ (/Users/egdelwonk/dev/lp/frontend/build/server/static/yNatTl7kpzkSAKqWfkbLL/pages/journals/templates/destination/detail.js:23:31)
at Object.nrlr (/Users/egdelwonk/dev/lp/frontend/build/server/static/yNatTl7kpzkSAKqWfkbLL/pages/journals/templates/destination/detail.js:10516:13)
at __webpack_require__ (/Users/egdelwonk/dev/lp/frontend/build/server/static/yNatTl7kpzkSAKqWfkbLL/pages/journals/templates/destination/detail.js:23:31)
at Object.Jrf2 (/Users/egdelwonk/dev/lp/frontend/build/server/static/yNatTl7kpzkSAKqWfkbLL/pages/journals/templates/destination/detail.js:4298:14)
at __webpack_require__ (/Users/egdelwonk/dev/lp/frontend/build/server/static/yNatTl7kpzkSAKqWfkbLL/pages/journals/templates/destination/detail.js:23:31)
at Module.oSZ7 (/Users/egdelwonk/dev/lp/frontend/build/server/static/yNatTl7kpzkSAKqWfkbLL/pages/journals/templates/destination/detail.js:12982:12)
at __webpack_require__ (/Users/egdelwonk/dev/lp/frontend/build/server/static/yNatTl7kpzkSAKqWfkbLL/pages/journals/templates/destination/detail.js:23:31)
at Object.12 (/Users/egdelwonk/dev/lp/frontend/build/server/static/yNatTl7kpzkSAKqWfkbLL/pages/journals/templates/destination/detail.js:488:18)
at __webpack_require__ (/Users/egdelwonk/dev/lp/frontend/build/server/static/yNatTl7kpzkSAKqWfkbLL/pages/journals/templates/destination/detail.js:23:31) type: 'TypeError', '$error': '$error' }
npm ERR! code ELIFECYCLE
npm ERR! errno 1
Hi, I'm not able to reproduce this error, could someone who is encountering this issue add a link to a repo or their next.config.js
?
On a minimal project publicRuntimeConfig
and serverRuntimeConfig
are both being populated during build. We also do have a test for this here
Hey, I am also seeing this error on production builds after upgrading to 9.0.0
. It worked fine on 8.1.0
.
Doing the following:
import getConfig from 'next/config'
console.log(getConfig())
seems to randomly switch between printing the config and undefined
during the build.
Here is our next.config.js
:
const withCss = require('@zeit/next-css')
const withSass = require('@zeit/next-sass')
const withImages = require('next-images')
const isDev = process.env.NODE_ENV === 'dev'
const withSassConfig = {
cssModules: true,
cssLoaderOptions: {
modules: true,
importLoaders: 1,
localIdentName: isDev ? '[name]__[local]--[hash:base64:5]' : '[sha1:hash:hex:4]',
},
}
const nextConfig = {
publicRuntimeConfig: {
// config vars..
},
}
const config = {
...withSassConfig,
...nextConfig,
webpack: webpackConfig => webpackConfig,
}
module.exports = withCss(withSass(withImages(config)))
Hi @timdavish, I'm still not able reproduce. It would help a lot if someone could create a minimal repo that shows this occurring 馃憤
Tested next.config.js
:
const withCss = require('@zeit/next-css')
const withSass = require('@zeit/next-sass')
const withImages = require('next-images')
const isDev = process.env.NODE_ENV === 'dev'
const withSassConfig = {
cssModules: true,
cssLoaderOptions: {
modules: true,
importLoaders: 1,
localIdentName: isDev ? '[name]__[local]--[hash:base64:5]' : '[sha1:hash:hex:4]',
},
}
const nextConfig = {
serverRuntimeConfig: {
secret: 'pass'
},
publicRuntimeConfig: {
hello: 'world'
},
}
const config = {
...withSassConfig,
...nextConfig,
webpack: webpackConfig => webpackConfig,
}
module.exports = withCss(withSass(withImages(config)))
pages/index.js
import getConfig from 'next/config'
console.log(getConfig())
export default () => <p>Hello world!!</p>
@timdavish I have the impression that there's some sort of race condition. When I run the build inside a docker container it fails, but when I run on my Mac directly it builds just fine
I'm running into this problem as well. My project is large so a minimal repro is going to be tricky, but I suspect that this is a race condition so it may not even be possible. Running the same command (NODE_ENV=production next build
) in two environments gets the same error on different pages in the app.
Early 2015 Macbook Pro (3.1 GHz Intel Core i7) I get the following:
{ TypeError: Cannot destructure property `publicRuntimeConfig` of 'undefined' or 'null'.
at Object.tpE7 (/Users/ericbaer/dev/work/lnc/constellation/web/.next/server/static/hAFgtwbpTC55qnszuIR1i/pages/inventory.js:4011:55)
Netlify CI Environment (node10 Docker image)
TypeError: Cannot destructure property `publicRuntimeConfig` of 'undefined' or 'null'.
5:12:27 PM: at Object.tpE7 (/opt/build/repo/web/.next/server/static/RVuMYAXq8hm_vjh7oqK4-/pages/order-acknowledgment.js:3740:55)
A few notable things about my project:
build.manifest
, static 87Mb output dir.const { set, uniq } = require(`lodash/fp`);
const { BundleAnalyzerPlugin } = require(`webpack-bundle-analyzer`);
const redirects = require(`./redirects`);
const { ANALYZE, API_ROOT } = process.env;
module.exports = {
publicRuntimeConfig: {
API_ROOT: API_ROOT || `http://localhost:8000/api/`,
},
exportPathMap: function() {
const staticPages = uniq(redirects.map(redirect => redirect.staticPage));
const staticExports = staticPages.reduce(
(memo, page) => set(page, { page }, memo),
{}
);
return {
"/": { page: `/` },
"/auth/signed-in": { page: `/auth/signed-in` },
...staticExports
};
},
webpack: function(config, options) {
if (!options.dev) {
config.devtool = `nosources-source-map`;
// Enable sourceMaps in UglifyJs
for (const plugin of config.plugins) {
if (plugin[`constructor`][`name`] === `UglifyJsPlugin`) {
plugin.options.sourceMap = true;
break;
}
}
}
return config;
}
};
It looks like when the require cache is cleared in static-checker.ts
it is wiping out next/config (which uses the require cache to persist the configuration afaik). I disabled the cache purge for next/config.js in static-checker.ts and the error no longer appears.
As far as how to replicate the issue... I'm not entirely sure. It seems like you'd need a decently large number of pages to compile (I have ~30) with a decently large compile time per page (largish component graph? Largish number of packages included on the page? Large kb?) to see the error. With these changes to static-checker below, the error goes away:
import { isPageStatic } from './utils'
export default function worker(
options: any,
callback: (err: Error | null, data?: any) => void
) {
try {
const { serverBundle, runtimeEnvConfig } = options || ({} as any)
const result = isPageStatic(serverBundle, runtimeEnvConfig)
// clear require.cache to prevent running out of memory
// since the cache is persisted by default
Object.keys(require.cache).map(modId => {
// Disable cache purge for next/config module to persist configuration
if (modId.endsWith("node_modules/next/config.js")) {
return;
}
const mod = require.cache[modId]
delete require.cache[modId]
if (mod.parent) {
const idx = mod.parent.children.indexOf(mod)
mod.parent.children.splice(idx, 1)
}
})
callback(null, result)
} catch (error) {
callback(error)
}
}
cc @ijjk
@egdelwonk thanks for the additional details, this makes more sense. I have submitted a PR addressing the problem here
Looks good, thanks @ijjk.
@egdelwonk Where does that code go to? Does one need to get inside node_modules and update code?
Will it be fixed officially or we have to hack like so?
@ryandcsg looks like @ijjk made a PR to fix it (slightly different approach, but it should work) and i'd imagine it's coming in the 9.0.1 release. It's on the canary branch, but hasn't made it to a 9.0.x canary release yet.
Hey! I'll release a canary now so you can use this fix.
Can confirm that the canary release fixes the issue. Thanks everyone!
I reproduced this bug on 9.4.2
Hey @ijjk - it seems like this bug has returned, as per the 16 upvotes there ^
No reproduction was given on the new comment so that makes it hard to look into.
@timneutkens reproduction repo, I tried to fix it, https://github.com/vercel/next.js/pull/15777
I've tried v9.5.2 which should include #15777 and we're still getting undefined
back from any getConfig
call it seems.
The sentry example also experiences this error, due to the setup in the _app.tsx file.
import * as Sentry from '@sentry/node'
import { RewriteFrames } from '@sentry/integrations'
import getConfig from 'next/config'
if (process.env.NEXT_PUBLIC_SENTRY_DSN) {
const config = getConfig()
const distDir = `${config.serverRuntimeConfig.rootDir}/.next`
Sentry.init({
enabled: process.env.NODE_ENV === 'production',
integrations: [
new RewriteFrames({
iteratee: (frame: any) => {
frame.filename = frame.filename.replace(distDir, 'app:///_next')
return frame
},
}),
],
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
})
}
having the same error as above, getConfig no longer works for some reason, and is returning undefined, which breaks sentry configs
I am having the same issue on nextjs 9.5.3 publicRuntimeConfig is not returning custom variables, but only NODE_ENV :(
We are having the same issue that when running in a docker container, the publicRuntimeConfig
does not appear to be set from runtime env vars. I've confirmed that they are set in the container and available on process.env
when the app is running, and they are available server side, but not client side. We are not using any static pages, but we are using getServerSideProps
.
I ran into the same issue in v9.5.3 and ended up downgrading to v9.0.2 which for now suits my needs.
Edit: v9.4.0 (and v9.1.0 and v9.2.0 and v9.3.0) also works fine for me. v9.5.0 doesn't and as mentioned above neither does v9.5.3.
Race condition seems to make sense here, if I follow the value of publicRuntimeConfig
while building it changes from an empty object to undefined
at some point and breaks the build.
I also ran into this issue and in my case it was introduced by this change in the 9.4.3 release.
Since this change all undefined properties of publicRuntimeConfig
are removed at build time, and if that happens for all the properties then publicRuntimeConfig
is seen as {}
which is in turn filtered out.
A workaround can be to add at least one property to publicRuntimeConfig
that is defined at build time, could be foo:'bar'.
In my case though the real problem was that I was not using getInitialProps
as documented here.
For anyone else running into this, I ended up building the Next.js app when running my docker container (instead of when building the image) in order to avoid having to use the publicRuntimeConfig
. I now just use standard build time env vars. It adds startup time, but solves this issue
I'm running into this issue in my Sentry config in [email protected]
, following the Sentry example mentioned by @ColeTownsend here.
Looking at the examples repo, it appears with-sentry
was updated 7 hours ago. It has a different setup altogether:
// utils/sentry
import * as Sentry from '@sentry/node'
import { RewriteFrames } from '@sentry/integrations'
export const init = () => {
if (process.env.NEXT_PUBLIC_SENTRY_DSN) {
const integrations = []
if (
process.env.NEXT_IS_SERVER === 'true' &&
process.env.NEXT_PUBLIC_SENTRY_SERVER_ROOT_DIR
) {
// For Node.js, rewrite Error.stack to use relative paths, so that source
// maps starting with ~/_next map to files in Error.stack with path
// app:///_next
integrations.push(
new RewriteFrames({
iteratee: (frame) => {
frame.filename = frame.filename.replace(
process.env.NEXT_PUBLIC_SENTRY_SERVER_ROOT_DIR,
'app:///'
)
frame.filename = frame.filename.replace('.next', '_next')
return frame
},
})
)
}
Sentry.init({
enabled: process.env.NODE_ENV === 'production',
integrations,
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
release: process.env.NEXT_PUBLIC_COMMIT_SHA,
})
}
}
// pages/_app.tsx
import { init } from '../utils/sentry'
init()
export default function App({ Component, pageProps, err }) {
// Workaround for https://github.com/vercel/next.js/issues/8592
return <Component {...pageProps} err={err} />
}
Changing my _app.tsx
file to use the new Sentry setup seems to have fixed this for me (given that getConfig()
returns undefined
and it's no longer used.)
Most helpful comment
I reproduced this bug on 9.4.2