Skip to content

Commit afe0d93

Browse files
committed
fix(cache): add null check for globalThis.openNextConfig
Adds optional chaining when accessing globalThis.openNextConfig to prevent TypeError during Next.js 16 build phase when using the Adapters API. The cache handler can be instantiated during SSG/prerendering before openNextConfig is initialized by the runtime handlers.
1 parent cdfbea1 commit afe0d93

File tree

3 files changed

+42
-4
lines changed

3 files changed

+42
-4
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
"@opennextjs/aws": patch
3+
---
4+
5+
fix: add null check for globalThis.openNextConfig in cache handler
6+
7+
Adds optional chaining when accessing globalThis.openNextConfig to prevent
8+
TypeError during Next.js 16 build phase when using the Adapters API. The cache
9+
handler can be instantiated during SSG/prerendering before openNextConfig is
10+
initialized by the runtime handlers.

packages/open-next/src/adapters/cache.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export default class Cache {
4545
kind?: "FETCH";
4646
},
4747
) {
48-
if (globalThis.openNextConfig.dangerous?.disableIncrementalCache) {
48+
if (globalThis.openNextConfig?.dangerous?.disableIncrementalCache) {
4949
return null;
5050
}
5151

@@ -204,7 +204,7 @@ export default class Cache {
204204
data?: IncrementalCacheValue,
205205
ctx?: IncrementalCacheContext,
206206
): Promise<void> {
207-
if (globalThis.openNextConfig.dangerous?.disableIncrementalCache) {
207+
if (globalThis.openNextConfig?.dangerous?.disableIncrementalCache) {
208208
return;
209209
}
210210
// This one might not even be necessary anymore
@@ -322,7 +322,7 @@ export default class Cache {
322322
}
323323

324324
public async revalidateTag(tags: string | string[]) {
325-
const config = globalThis.openNextConfig.dangerous;
325+
const config = globalThis.openNextConfig?.dangerous;
326326
if (config?.disableTagCache || config?.disableIncrementalCache) {
327327
return;
328328
}
@@ -430,7 +430,7 @@ export default class Cache {
430430
ctx?: IncrementalCacheContext,
431431
) {
432432
if (
433-
globalThis.openNextConfig.dangerous?.disableTagCache ||
433+
globalThis.openNextConfig?.dangerous?.disableTagCache ||
434434
globalThis.tagCache.mode === "nextMode" ||
435435
// Here it means it's a delete
436436
!data

packages/tests-unit/tests/adapters/cache.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,34 @@ describe("CacheHandler", () => {
8585
expect(result).toBeNull();
8686
});
8787

88+
describe("undefined openNextConfig", () => {
89+
it("Should not throw when globalThis.openNextConfig is undefined", async () => {
90+
// @ts-expect-error - Testing undefined config scenario
91+
globalThis.openNextConfig = undefined;
92+
93+
// Should not throw TypeError: Cannot read properties of undefined (reading 'dangerous')
94+
const result = await cache.get("key");
95+
96+
expect(result).not.toBeUndefined();
97+
});
98+
99+
it("Should not throw on set when globalThis.openNextConfig is undefined", async () => {
100+
// @ts-expect-error - Testing undefined config scenario
101+
globalThis.openNextConfig = undefined;
102+
103+
await expect(
104+
cache.set("key", { kind: "REDIRECT", props: {} }),
105+
).resolves.not.toThrow();
106+
});
107+
108+
it("Should not throw on revalidateTag when globalThis.openNextConfig is undefined", async () => {
109+
// @ts-expect-error - Testing undefined config scenario
110+
globalThis.openNextConfig = undefined;
111+
112+
await expect(cache.revalidateTag("tag")).resolves.not.toThrow();
113+
});
114+
});
115+
88116
describe("disableIncrementalCache", () => {
89117
beforeEach(() => {
90118
globalThis.openNextConfig.dangerous.disableIncrementalCache = true;

0 commit comments

Comments
 (0)