Skip to content

fix(hosting): use nodejs24.x for SSR framework compute and fail loudly on unknown runtimes (#361) - #374

Open
sarayev wants to merge 4 commits into
mainfrom
fix/issue-361-nodejs24-runtime
Open

fix(hosting): use nodejs24.x for SSR framework compute and fail loudly on unknown runtimes (#361)#374
sarayev wants to merge 4 commits into
mainfrom
fix/issue-361-nodejs24-runtime

Conversation

@sarayev

@sarayev sarayev commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #361. AWS Blocks Hosting was deploying SSR framework Lambdas (Nuxt/Nitro, Astro, SvelteKit, Next.js) on the deprecated nodejs20.x runtime, and resolveRuntime() silently fell back to Node 20 for any runtime it didn't recognize — masking the problem and making a partial fix ineffective.

Changes

  • New shared constants (framework_runtime.ts): FRAMEWORK_COMPUTE_RUNTIME = 'nodejs24.x' for regional SSR compute and FRAMEWORK_EDGE_COMPUTE_RUNTIME = 'nodejs24.x' for Lambda@Edge. Adapters reference these instead of hardcoded literals, so future bumps are a one-line change.
  • resolveRuntime() now recognizes nodejs24.x, defaults to nodejs24.x when no runtime is declared, and throws UnsupportedRuntimeError (with the list of supported values) instead of silently returning NODEJS_20_X.
  • Updated adapters: nitro.ts (both presets), astro.ts, sveltekit.ts, nextjs.ts (regional/server-function and Lambda@Edge paths).
  • Corrected a misleading comment in node_runtime.ts that implied the adapters detect the framework's compiled Node version (they don't — the runtime is a fixed shared constant).
  • Also fixed two hosting-owned handlers (ISR revalidation worker + tag-table seed) that were pinned to Node 20 against the stated DEFAULT_NODE_RUNTIME contract.

Lambda@Edge: also bumped to nodejs24.x

An earlier revision of this PR left the edge path on nodejs20.x out of caution. That decision has been revised — the edge path is now bumped too:

  1. Lambda@Edge supports Node 24. For Node.js, Lambda@Edge draws from the same managed runtime table as regional Lambda: nodejs24.x is supported (deprecates 2028-04-30), while nodejs20.x is already past its 2026-04-30 deprecation, so it can no longer back newly-created edge functions. Staying on Node 20 was the riskier option.
  2. The OpenNext banner patch was revalidated. patchEdgeBundlesForLambdaEdge rewrites OpenNext's import * as process from "node:process" banner. The TypeError: Cannot assign to read only property 'env' of object '[object Module]' it works around is spec-level behavior — ES Module namespace object bindings are non-writable per ECMA-262 — not a Node 20 quirk. Its replacement (const process = (await import("node:process")).default;) relies only on top-level await import(...) and the long-stable node:process default export, both of which behave identically on Node 20, 22, and 24. There is no Node-version-specific assumption in the patch, so no fallback to nodejs22.x was needed.

Code comments in framework_runtime.ts and nextjs.ts were updated to record this reasoning and to drop the now-inaccurate "Node 20 ESM semantics" framing.

Testing

  • npm run build — clean (tsc --build + handler bundling), Node 22
  • npm test832/832 pass, 0 fail (+3 new tests): default runtime resolves to nodejs24.x; explicit nodejs22.x honored; unrecognized runtime (python3.12) throws UnsupportedRuntimeError.
  • Existing tests asserting nodejs20.x (regional and edge) updated to nodejs24.x.

Note: resolveRuntime() still accepts explicit nodejs20.x/nodejs18.x from a user-supplied manifest — this change only moves the framework-emitted defaults.

… workflow

The PR head branch name was interpolated directly into a run: shell body,
allowing someone who opens a PR from a branch named release/swift-<payload>
to execute arbitrary shell commands on the runner, which has a
contents:write GITHUB_TOKEN available.

- Pass github.event.pull_request.head.ref via env: instead of inlining it
- Pass steps.version.outputs.version via env: (second-order taint)
- Add a SemVer allowlist + explicit newline guard before tagging
… on unknown runtimes (#361)

- resolveRuntime: recognize nodejs24.x, default to nodejs24.x when no runtime
  is declared, and throw HostingError('UnsupportedRuntimeError') instead of
  silently falling back to nodejs20.x
- add shared FRAMEWORK_COMPUTE_RUNTIME / FRAMEWORK_EDGE_COMPUTE_RUNTIME
  constants and reference them from the Next.js, Nitro, Astro and SvelteKit
  adapters instead of hardcoded 'nodejs20.x' literals
- keep Lambda@Edge compute on nodejs20.x (documented in framework_runtime.ts)
- use DEFAULT_NODE_RUNTIME for the hosting-owned ISR revalidation and
  tag-table seed handlers
- correct the node_runtime.ts scope comment (no framework Node detection exists)
- update runtime expectations in tests and cover the throwing path
@sarayev
sarayev requested a review from a team as a code owner August 14, 2026 14:02
@changeset-bot

changeset-bot Bot commented Aug 14, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: b05160c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@aws-blocks/hosting Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Lambda@Edge draws its Node.js versions from the same managed runtime
table as regional Lambda: nodejs24.x is supported (deprecates
2028-04-30) while nodejs20.x is already past its 2026-04-30
deprecation, so new edge functions can no longer be created on it.

Revalidated patchEdgeBundlesForLambdaEdge: the TypeError it works
around comes from ES Module namespace exports being non-writable per
the ECMAScript spec, not from Node 20 semantics, and the replacement
uses only top-level await import() plus the node:process default
export - both stable across Node 18-24.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(hosting): Nuxt SSR (and other frameworks) Lambda is pinned to deprecated nodejs20.x (undocumented), compute construct also uses old node versions

1 participant