Skip to content

Plan Undici 8 migration after dropping Node 20 support #232

@GrahamCampbell

Description

@GrahamCampbell

We currently depend on undici and use it directly for fetch dispatchers, while most request execution still uses the Node global fetch.

Current direct usage:

  • lib/utils/serverless-utils/download.js: imports Agent and passes it as a fetch dispatcher for rejectUnauthorized: false downloads.
  • lib/plugins/plugin/lib/utils.js: imports ProxyAgent and passes it as a fetch dispatcher for plugin registry requests through proxy env vars.
  • Additional direct fetch call sites use the global implementation: rollback-function.js, download-template-from-repo.js, standalone.js, and utils/standalone.js.

undici@8.2.0 currently declares engines: { node: ">=22.19.0" }, so it is not compatible with the current project engine range of ^20.19.0 || ^22.13.0 || >=24.

Undici 8 also changes lower-level dispatcher internals. To avoid mixing Undici 8 dispatchers with Node built-in global fetch, the migration should use undici.fetch consistently for direct fetch usage.

Proposed Scope

  • Raise the package Node engine floor to at least >=22.19.0 after Node 20 support is intentionally dropped.
  • Upgrade undici to ^8.2.0 or the latest compatible 8.x release at the time of the change.
  • Import fetch from undici at all direct fetch call sites in lib.
  • In serverless-utils/download.js, import Headers from undici as well so fetch, Headers, and Agent come from the same implementation.
  • Keep AWS SDK HTTP handling out of scope.
  • Keep generated/runtime custom resource https usage out of scope.

Direct Fetch Call Sites To Review

  • lib/utils/serverless-utils/download.js
  • lib/plugins/plugin/lib/utils.js
  • lib/plugins/aws/rollback-function.js
  • lib/utils/download-template-from-repo.js
  • lib/plugins/standalone.js
  • lib/utils/standalone.js

Test Updates

  • Replace tests that monkeypatch globalThis.fetch with proxyquire stubs for undici.fetch, or use Undici MockAgent where integration-style behavior is needed.
  • Preserve coverage for manual redirects and redirect body cancellation in serverless-utils/download.
  • Preserve coverage that proxy-backed plugin registry fetches pass a dispatcher.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions