GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — fix(sdk): fallback for AbortSignal.any in chat transport on Safari < 17.4 (#5098) by ghazy2001 · Pull Request #5107 · triggerdotdev/trigger.dev

Conversation

@ghazy2001

@ghazy2001 ghazy2001 commented Nov 10, 2026

Copy link
Copy Markdown

Overview

Fixes #5098

On Safari < 17.4 (and Node < 20.3), \AbortSignal.any\ is undefined, causing chat transports (\useTriggerChatTransport, \subscribeToSessionStream,
econnectToStream) to throw:
\
TypeError: AbortSignal.any is not a function. (In 'AbortSignal.any([t,o.signal])', 'AbortSignal.any' is undefined)
\\

Changes

  • **\�nySignal\ helper in \�i-shared.ts**:
    • Delegates to native \AbortSignal.any\ when available.
    • Implements an \AbortController-backed fallback on older browsers and runtimes.
    • Returns immediately if an input signal is already aborted, preserving the abort reason.
    • Automatically cleans up event listeners on all other signals once any signal aborts, preventing memory leaks on reused caller signals.
  • Replaced direct \AbortSignal.any\ call sites:
    • \packages/trigger-sdk/src/v3/chat.ts\ (
      econnectToStream\ and \subscribeToSessionStream)
    • \packages/trigger-sdk/src/v3/chat-client.ts\ (\subscribeToSessionStream)
    • \packages/trigger-sdk/src/v3/chat-server.ts\ (\openHandoverSession)
    • \packages/trigger-sdk/src/v3/ai.ts\ (\chatAgent\ and \createChatSession)
  • Unit Tests:
    • \packages/trigger-sdk/src/v3/ai-shared.test.ts: 8 unit tests covering single signal, empty signal list, native \AbortSignal.any, fallback when \AbortSignal.any\ is undefined (already aborted, first aborted, second aborted, listener cleanup).
    • \packages/trigger-sdk/src/v3/chat.test.ts: test verifying
      econnectToStream\ safely handles aborted signals when \AbortSignal.any\ is deleted.

Verification

  • Ran Vitest suite on \src/v3/ai-shared.test.ts\ and \src/v3/chat.test.ts\ (92/92 passed).
  • Verified TypeScript compilation (\ sc --noEmit) with 0 errors in affected files.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@ghazy2001
fix(sdk): fallback for AbortSignal.any in chat transport on Safari < …
47081d6
…17.4 (triggerdotdev#5098)
@changeset-bot

changeset-bot Bot commented Nov 10, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 47081d6

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ghazy2001 ghazy2001 mentioned this pull request Nov 10, 2026
bug: Chat transport crashes on Safari < 17.4: AbortSignal.any is not a function #5098
Open
@github-actions

github-actions Bot commented Nov 10, 2026

Copy link
Copy Markdown
Contributor

Hi @ghazy2001, thanks for your interest in contributing!

This project requires that pull request authors are vouched, and you are not in the list of vouched users.

This PR will be closed automatically. See https://github.com/triggerdotdev/trigger.dev/blob/main/CONTRIBUTING.md for more details.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions github-actions Bot closed this Nov 10, 2026
@coderabbitai

coderabbitai Bot commented Nov 10, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Explain Change →

Caution

Review failed

The pull request is closed.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

  • X
  • Mastodon
  • Reddit
  • LinkedIn
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

devin-ai-integration[bot]
devin-ai-integration Bot reviewed Nov 10, 2026
View reviewed changes

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

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Devin Review found 5 potential issues.

Devin Review

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread packages/trigger-sdk/src/v3/ai-shared.ts
Comment on lines +321 to +323
for (const signal of validSignals) {
signal.addEventListener("abort", onAbort, { once: true });
}

@devin-ai-integration devin-ai-integration Bot Nov 10, 2026

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

🟡 Completed turns retain abort listeners

On runtimes without AbortSignal.any, anySignal retains listeners after a normal chat turn completes. Neither runSignal nor the per-turn stop signal aborts, so long-lived runs accumulate listeners and controllers.

Learn more

The fallback subscribes to each input signal and removes those listeners only when an input aborts. A managed chat turn creates a new stop controller and combines it with the run-wide signal in the turn setup. Normal completion does not abort either signal, so the run-wide signal keeps every prior turn's closure, controller, and stop signal alive. The custom session turn also replaces its stop controller without aborting the old one in reset. This differs from native AbortSignal.any, which does not keep an otherwise unreferenced composite alive through strong event listeners.

Example: On a runtime without AbortSignal.any, a chat agent finishes 80 normal turns. Its run-wide signal still holds 80 listeners referencing obsolete stop controllers until the run ends.

Recommended fix: Provide a way to dispose the fallback's source listeners when the composite's operation ends, and invoke it at each turn and subscription teardown. Preserve the existing abort propagation and reason while an operation remains active.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread packages/trigger-sdk/src/v3/ai-shared.ts
* with listeners on environments where `AbortSignal.any` is not supported (such as
* Safari < 17.4 or Node < 20.3).
*/
export function anySignal(signals: (AbortSignal | undefined | null)[]): AbortSignal {

@devin-ai-integration devin-ai-integration Bot Nov 10, 2026

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

🟡 Safari fix lacks a release changeset

The anySignal fallback fixes a user-visible SDK failure, but this PR includes no changeset. The SDK release loses its required patch note.

Learn more

The SDK is a public package, and the new fallback lets customers use chat transports on older Safari versions that previously threw. Repository guidance requires a changeset when a public package fixes a bug users could hit. No changeset is added in this PR.

Example: A customer deciding whether to upgrade for Safari support reads the SDK changelog and finds no entry for the fix.

Recommended fix: Add a patch changeset for @trigger.dev/sdk, phrased in terms of older Safari chat transport compatibility.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread packages/trigger-sdk/src/v3/ai-shared.test.ts
const c1 = new AbortController();
const c2 = new AbortController();

const c2RemoveSpy = vi.spyOn(c2.signal, "removeEventListener");

@devin-ai-integration devin-ai-integration Bot Nov 10, 2026

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

🟡 Fallback test uses a forbidden spy

The listener-cleanup test calls vi.spyOn, despite the repository's explicit ban on spies in tests. Its assertion also couples the test to listener-removal internals.

Learn more

Example: A fallback implementation that manages listeners through another valid mechanism can fail the test solely because it never calls the spied-on method.

Recommended fix: Replace the spy with an observable behavioral test that covers the listener-lifetime regression without intercepting removeEventListener.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread packages/trigger-sdk/src/v3/ai-shared.test.ts
Comment on lines +4 to +5
describe("anySignal", () => {
it("returns a non-aborted signal when signals list is empty", () => {

@devin-ai-integration devin-ai-integration Bot Nov 10, 2026

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

🔍 Identify each unit test’s regression

The new unit tests lack the required // Catches: <bug> comments. Identify each distinct regression they protect and remove redundant cases.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread packages/trigger-sdk/src/v3/chat.test.ts
Comment on lines +2472 to +2473
expect(stream).toBeDefined();
abort.abort();

@devin-ai-integration devin-ai-integration Bot Nov 10, 2026

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

🔍 Transport abort is not asserted

The Safari test calls abort.abort() without consuming the stream. It cannot detect a subscription that remains open after abort.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@devin-ai-integration devin-ai-integration[bot] devin-ai-integration[bot] left review comments

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

bug: Chat transport crashes on Safari < 17.4: AbortSignal.any is not a function

Uh oh!

There was an error while loading. Please reload this page.

1 participant

@ghazy2001
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.