Skip to content

Conversation

@claude
Copy link

@claude claude bot commented Jan 24, 2026

Summary

  • Vendors superjson@2.2.1 using esbuild to create both CJS and ESM bundles
  • Updates the superjson wrapper modules to use the vendored bundles instead of the npm package directly
  • Fixes the ERR_REQUIRE_ESM error that occurs when using @trigger.dev/core in CJS environments with Node.js < 22.12

Problem

The superjson package v2.x is ESM-only, but Node.js versions < 22.12 don't support require() of ESM modules. This causes the following error when using @trigger.dev/core in CJS environments:

require() of ES Module /path/to/node_modules/superjson/dist/index.js from /path/to/node_modules/@trigger.dev/core/dist/commonjs/v3/imports/superjson-cjs.cjs not supported.

Solution

The fix bundles superjson@2.2.1 using esbuild into both CJS (superjson.cjs) and ESM (superjson.js) formats in a new vendor/ directory. The existing wrapper modules (superjson.ts and superjson-cjs.cts) are updated to import from these vendored bundles instead of the npm package directly.

This ensures the package works correctly in all environments without relying on Node.js's experimental require(ESM) feature.

Test plan

  • All 402 tests in @trigger.dev/core pass
  • Build succeeds with pnpm --filter @trigger.dev/core run build
  • Verified vendored superjson produces identical serialization format as original npm package

Fixes #2937

🤖 Generated with Claude Code


Open with Devin

This fixes the ERR_REQUIRE_ESM error that occurs when using @trigger.dev/core
in CJS environments with Node.js versions < 22.12. The superjson package (v2.x)
is ESM-only, but Node.js doesn't support require() of ESM modules in older
versions.

The fix bundles superjson@2.2.1 using esbuild into both CJS and ESM formats,
which are then imported by the existing wrapper modules. This ensures the
package works correctly in all environments without relying on Node.js's
experimental require(ESM) feature.

Fixes #2937

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@changeset-bot
Copy link

changeset-bot bot commented Jan 24, 2026

🦋 Changeset detected

Latest commit: 3375d3d

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

This PR includes changesets to release 27 packages
Name Type
@trigger.dev/core Patch
@trigger.dev/build Patch
trigger.dev Patch
@trigger.dev/python Patch
@trigger.dev/redis-worker Patch
@trigger.dev/schema-to-json Patch
@trigger.dev/sdk Patch
@internal/cache Patch
@internal/clickhouse Patch
@internal/redis Patch
@internal/replication Patch
@internal/run-engine Patch
@internal/schedule-engine Patch
@internal/testcontainers Patch
@internal/tracing Patch
@internal/tsql Patch
@internal/zod-worker Patch
d3-chat Patch
references-d3-openai-agents Patch
references-nextjs-realtime Patch
references-realtime-hooks-test Patch
references-realtime-streams Patch
references-telemetry Patch
@trigger.dev/react-hooks Patch
@trigger.dev/rsc Patch
@trigger.dev/database Patch
@trigger.dev/otlp-importer 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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 24, 2026

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Comment @coderabbitai help to get the list of available commands and usage tips.

var isURL = (payload) => payload instanceof URL;

// ../../node_modules/.pnpm/superjson@2.2.1/node_modules/superjson/dist/pathstringifier.js
var escapeKey = (key) => key.replace(/\./g, "\\.");

Check failure

Code scanning / CodeQL

Incomplete string escaping or encoding High library

This does not escape backslash characters in the input.

Copilot Autofix

AI about 5 hours ago

In general, to fix this class of problems you must escape the escape character itself before (or while) escaping other meta-characters, and ensure that the parser correctly inverts the escaping. Here, that means encoding backslashes in a reversible way before turning dots into \.. The decoder (parsePath) then needs to understand both the escaped dots and escaped backslashes.

The best minimal fix without changing overall functionality is:

  • Change escapeKey so that it first escapes existing backslashes (e.g., replace \ with \\ globally), then escapes dots by turning . into \.. This ensures that any \. seen by the parser must have been produced by the escaping step, not from an original backslash+dot in the key.
  • Update parsePath so that:
    • It recognizes \. as an escaped dot (current behavior).
    • It also recognizes \\ as an escaped backslash and appends a single \ to the segment.
    • Other backslashes are treated literally.

To keep the change minimal and localized, we only modify the escapeKey function and the loop in parsePath in packages/core/src/v3/vendor/superjson.cjs. No new imports or external libraries are needed; we can implement this with built-in string methods and simple control flow.

Concretely:

  • At line 195, replace var escapeKey = (key) => key.replace(/\./g, "\\."); with a version that first escapes backslashes: var escapeKey = (key) => key.replace(/\\/g, "\\\\").replace(/\./g, "\\.");
  • In parsePath, adjust the character loop so it checks for \\ (escaped backslash) and \. (escaped dot) in order, handles them appropriately, and only treats an unescaped . as a segment separator.
Suggested changeset 1
packages/core/src/v3/vendor/superjson.cjs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/packages/core/src/v3/vendor/superjson.cjs b/packages/core/src/v3/vendor/superjson.cjs
--- a/packages/core/src/v3/vendor/superjson.cjs
+++ b/packages/core/src/v3/vendor/superjson.cjs
@@ -192,13 +192,19 @@
 var isURL = (payload) => payload instanceof URL;
 
 // ../../node_modules/.pnpm/superjson@2.2.1/node_modules/superjson/dist/pathstringifier.js
-var escapeKey = (key) => key.replace(/\./g, "\\.");
+var escapeKey = (key) => key.replace(/\\/g, "\\\\").replace(/\./g, "\\.");
 var stringifyPath = (path) => path.map(String).map(escapeKey).join(".");
 var parsePath = (string) => {
   const result = [];
   let segment = "";
   for (let i = 0; i < string.length; i++) {
     let char = string.charAt(i);
+    const isEscapedBackslash = char === "\\" && string.charAt(i + 1) === "\\";
+    if (isEscapedBackslash) {
+      segment += "\\";
+      i++;
+      continue;
+    }
     const isEscapedDot = char === "\\" && string.charAt(i + 1) === ".";
     if (isEscapedDot) {
       segment += ".";
EOF
@@ -192,13 +192,19 @@
var isURL = (payload) => payload instanceof URL;

// ../../node_modules/.pnpm/superjson@2.2.1/node_modules/superjson/dist/pathstringifier.js
var escapeKey = (key) => key.replace(/\./g, "\\.");
var escapeKey = (key) => key.replace(/\\/g, "\\\\").replace(/\./g, "\\.");
var stringifyPath = (path) => path.map(String).map(escapeKey).join(".");
var parsePath = (string) => {
const result = [];
let segment = "";
for (let i = 0; i < string.length; i++) {
let char = string.charAt(i);
const isEscapedBackslash = char === "\\" && string.charAt(i + 1) === "\\";
if (isEscapedBackslash) {
segment += "\\";
i++;
continue;
}
const isEscapedDot = char === "\\" && string.charAt(i + 1) === ".";
if (isEscapedDot) {
segment += ".";
Copilot is powered by AI and may make mistakes. Always verify output.
var isURL = (payload) => payload instanceof URL;

// ../../node_modules/.pnpm/superjson@2.2.1/node_modules/superjson/dist/pathstringifier.js
var escapeKey = (key) => key.replace(/\./g, "\\.");

Check failure

Code scanning / CodeQL

Incomplete string escaping or encoding High library

This does not escape backslash characters in the input.

Copilot Autofix

AI about 5 hours ago

In general, when designing a custom escaping scheme that uses backslash as the escape character, you must first escape existing backslashes before escaping other characters (such as .) so that decoding can correctly distinguish literal backslashes from escapes. Here, escapeKey currently only escapes dots by turning . into \. but never doubles existing backslashes. parsePath, however, interprets \. specially as an escaped dot and does not treat \\ as a literal backslash escape, so a key with backslashes can be misparsed.

The best fix, without changing external behavior for existing “simple” keys, is to extend both the encoder (escapeKey) and decoder (parsePath) to handle backslashes in a symmetric way. A straightforward scheme is:

  • In escapeKey, first escape backslashes by replacing each \ with \\, then escape dots by replacing . with \.. This ensures any sequence that looks like an escape in the encoded string was deliberately produced by escapeKey.
  • In parsePath, interpret \\ as a literal backslash and \. as a literal dot, and treat any other backslash as a literal backslash followed by the next character. This makes decoding robust and preserves round-tripping even if other characters follow a backslash.

Concretely:

  • Modify line 161 to add a backslash-escaping step before the existing dot-escaping.
  • Adjust the loop in parsePath (lines 166–181) so it can decode \\ and \. correctly, rather than only handling \.. This change is fully local to packages/core/src/v3/vendor/superjson.js and requires no new imports or external dependencies.
Suggested changeset 1
packages/core/src/v3/vendor/superjson.js

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/packages/core/src/v3/vendor/superjson.js b/packages/core/src/v3/vendor/superjson.js
--- a/packages/core/src/v3/vendor/superjson.js
+++ b/packages/core/src/v3/vendor/superjson.js
@@ -158,17 +158,26 @@
 var isURL = (payload) => payload instanceof URL;
 
 // ../../node_modules/.pnpm/superjson@2.2.1/node_modules/superjson/dist/pathstringifier.js
-var escapeKey = (key) => key.replace(/\./g, "\\.");
+var escapeKey = (key) => key.replace(/\\/g, "\\\\").replace(/\./g, "\\.");
 var stringifyPath = (path) => path.map(String).map(escapeKey).join(".");
 var parsePath = (string) => {
   const result = [];
   let segment = "";
   for (let i = 0; i < string.length; i++) {
-    let char = string.charAt(i);
-    const isEscapedDot = char === "\\" && string.charAt(i + 1) === ".";
-    if (isEscapedDot) {
-      segment += ".";
-      i++;
+    const char = string.charAt(i);
+    if (char === "\\") {
+      const nextChar = string.charAt(i + 1);
+      if (nextChar === "\\") {
+        segment += "\\";
+        i++;
+        continue;
+      }
+      if (nextChar === ".") {
+        segment += ".";
+        i++;
+        continue;
+      }
+      segment += "\\";
       continue;
     }
     const isEndOfSegment = char === ".";
EOF
@@ -158,17 +158,26 @@
var isURL = (payload) => payload instanceof URL;

// ../../node_modules/.pnpm/superjson@2.2.1/node_modules/superjson/dist/pathstringifier.js
var escapeKey = (key) => key.replace(/\./g, "\\.");
var escapeKey = (key) => key.replace(/\\/g, "\\\\").replace(/\./g, "\\.");
var stringifyPath = (path) => path.map(String).map(escapeKey).join(".");
var parsePath = (string) => {
const result = [];
let segment = "";
for (let i = 0; i < string.length; i++) {
let char = string.charAt(i);
const isEscapedDot = char === "\\" && string.charAt(i + 1) === ".";
if (isEscapedDot) {
segment += ".";
i++;
const char = string.charAt(i);
if (char === "\\") {
const nextChar = string.charAt(i + 1);
if (nextChar === "\\") {
segment += "\\";
i++;
continue;
}
if (nextChar === ".") {
segment += ".";
i++;
continue;
}
segment += "\\";
continue;
}
const isEndOfSegment = char === ".";
Copilot is powered by AI and may make mistakes. Always verify output.
Copy link

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 3 additional flags.

Open in Devin Review

@vibe-kanban-cloud
Copy link

Review Complete

Your review story is ready!

View Story

Comment !reviewfast on this PR to re-generate the story.

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: Error [ERR_REQUIRE_ESM]: require()

1 participant