diff --git a/packages/core/src/v3/utils/ioSerialization.ts b/packages/core/src/v3/utils/ioSerialization.ts index cbea46671e..c3b4adc7f0 100644 --- a/packages/core/src/v3/utils/ioSerialization.ts +++ b/packages/core/src/v3/utils/ioSerialization.ts @@ -400,7 +400,15 @@ interface ReplacerOptions { } function makeSafeReplacer(options?: ReplacerOptions) { + const seen = new WeakSet(); + return function replacer(key: string, value: any) { + if (typeof value === "object" && value !== null) { + if (seen.has(value)) { + return "[Circular]"; + } + seen.add(value); + } // Check if the key should be filtered out if (options?.filteredKeys?.includes(key)) { return undefined; diff --git a/references/hello-world/src/trigger/example.ts b/references/hello-world/src/trigger/example.ts index 771834a6dd..6c527360e7 100644 --- a/references/hello-world/src/trigger/example.ts +++ b/references/hello-world/src/trigger/example.ts @@ -301,3 +301,30 @@ export const resourceMonitorTest = task({ }; }, }); + +export const circularReferenceTask = task({ + id: "circular-reference", + run: async (payload: { message: string }, { ctx }) => { + logger.info("Hello, world from the circular reference task", { message: payload.message }); + + // Create an object + const user = { + name: "Alice", + details: { + age: 30, + email: "alice@example.com", + }, + }; + + // Create the circular reference + // @ts-expect-error - This is a circular reference + user.details.user = user; + + // Now user.details.user points back to the user object itself + // This creates a circular reference that standard JSON can't handle + + return { + user, + }; + }, +});