From 140fc20e4978ed46b18fd41a619bfb156d27c116 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 15 Feb 2026 06:18:46 +0000 Subject: [PATCH] Cover zero-width-non-joiner wrapper baseURL rejection Co-authored-by: Eric Allam --- docs/tasks/streams.mdx | 1 + packages/ai/README.md | 1 + packages/ai/src/chatTransport.test.ts | 22 ++++++++++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/docs/tasks/streams.mdx b/docs/tasks/streams.mdx index e16f14550..7bfb4d375 100644 --- a/docs/tasks/streams.mdx +++ b/docs/tasks/streams.mdx @@ -671,6 +671,7 @@ Examples: - ✅ `\uFEFFhttps://api.trigger.dev/custom-prefix/\uFEFF` (BOM wrapper trimmed) - ❌ `\u2060https://api.trigger.dev/custom-prefix/\u2060` (word-joiner wrappers are rejected) - ❌ `\u200Bhttps://api.trigger.dev/custom-prefix/\u200B` (zero-width-space wrappers are rejected) +- ❌ `\u200Chttps://api.trigger.dev/custom-prefix/\u200C` (zero-width-non-joiner wrappers are rejected) - ❌ `https://api.trigger.dev?foo=bar` - ❌ `https://api.trigger.dev#fragment` - ❌ `https://user:pass@api.trigger.dev` diff --git a/packages/ai/README.md b/packages/ai/README.md index e6af6818d..422bfafc7 100644 --- a/packages/ai/README.md +++ b/packages/ai/README.md @@ -178,6 +178,7 @@ Examples: - ✅ `\uFEFFhttps://api.trigger.dev/custom-prefix/\uFEFF` (BOM wrapper trimmed) - ❌ `\u2060https://api.trigger.dev/custom-prefix/\u2060` (word-joiner wrappers are rejected) - ❌ `\u200Bhttps://api.trigger.dev/custom-prefix/\u200B` (zero-width-space wrappers are rejected) +- ❌ `\u200Chttps://api.trigger.dev/custom-prefix/\u200C` (zero-width-non-joiner wrappers are rejected) - ❌ `https://api.trigger.dev?foo=bar` (query string) - ❌ `https://api.trigger.dev#fragment` (hash fragment) - ❌ `https://user:pass@api.trigger.dev` (credentials) diff --git a/packages/ai/src/chatTransport.test.ts b/packages/ai/src/chatTransport.test.ts index e784a22e3..75c00d45f 100644 --- a/packages/ai/src/chatTransport.test.ts +++ b/packages/ai/src/chatTransport.test.ts @@ -852,6 +852,17 @@ describe("TriggerChatTransport", function () { }).toThrowError("baseURL must not contain internal whitespace characters"); }); + it("throws when baseURL is wrapped with zero-width-non-joiner characters", function () { + expect(function () { + new TriggerChatTransport({ + task: "chat-task", + accessToken: "pk_trigger", + baseURL: "\u200Chttps://api.trigger.dev/custom-prefix/\u200C", + stream: "chat-stream", + }); + }).toThrowError("baseURL must not contain internal whitespace characters"); + }); + it("throws when baseURL contains internal zero-width-non-joiner characters", function () { expect(function () { new TriggerChatTransport({ @@ -3646,6 +3657,17 @@ describe("TriggerChatTransport", function () { }).toThrowError("baseURL must not contain internal whitespace characters"); }); + it("throws from factory when baseURL is wrapped with zero-width-non-joiner characters", function () { + expect(function () { + createTriggerChatTransport({ + task: "chat-task", + accessToken: "pk_trigger", + baseURL: "\u200Chttps://api.trigger.dev/custom-prefix/\u200C", + stream: "chat-stream", + }); + }).toThrowError("baseURL must not contain internal whitespace characters"); + }); + it("throws from factory when baseURL contains internal zero-width-non-joiner characters", function () { expect(function () { createTriggerChatTransport({