Skip to content

Allow branded types in eventType schemas#1442

Open
amh4r wants to merge 2 commits intomainfrom
aaron/exe-1559-bug-branded-types-incorrectly-flagged-as-transforms
Open

Allow branded types in eventType schemas#1442
amh4r wants to merge 2 commits intomainfrom
aaron/exe-1559-bug-branded-types-incorrectly-flagged-as-transforms

Conversation

@amh4r
Copy link
Copy Markdown
Contributor

@amh4r amh4r commented Apr 4, 2026

Allow branded types in eventType schemas. Previously, they would cause a type error because we considered them a "transform".

We intentionally don't have StandardSchema transform support. But our check for the existence of a transform (input and output types differ) was too coarse-grained. It errored on branded types as well, even though branded types don't cause a runtime transformation.

https://linear.app/inngest/issue/EXE-1559


Note

This PR fixes a false-positive transform error for Zod branded types by introducing StripSymbolKeys<T> to remove symbol-keyed properties before comparing schema input/output types in AssertNoTransform.

Written by Mendral for commit da45a45.

@linear
Copy link
Copy Markdown

linear bot commented Apr 4, 2026

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 4, 2026

🦋 Changeset detected

Latest commit: da45a45

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

This PR includes changesets to release 1 package
Name Type
inngest 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

@inngest-release-bot inngest-release-bot added the 📦 inngest Affects the `inngest` package label Apr 4, 2026
Copy link
Copy Markdown

@mendral-app mendral-app bot left a comment

Choose a reason for hiding this comment

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

High risk — 1 issue in 1 file

StripSymbolKeys<T> has no base case for primitives — StripSymbolKeys<string> and StripSymbolKeys<number> both resolve to {}, making IsEqualIgnoringBrands<string, number> return true. This means a schema with .transform(Number) (string→number) would silently bypass the transform guard, defeating the entire purpose of AssertNoTransform.

Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.

<assessment>
`StripSymbolKeys<T>` has no base case for primitives — `StripSymbolKeys<string>` and `StripSymbolKeys<number>` both resolve to `{}`, making `IsEqualIgnoringBrands<string, number>` return `true`. This means a schema with `.transform(Number)` (string→number) would silently bypass the transform guard, defeating the entire purpose of `AssertNoTransform`.
</assessment>

<file name="packages/inngest/src/components/triggers/triggers.ts">
<issue location="packages/inngest/src/components/triggers/triggers.ts:208">
Missing base case for primitives causes `StripSymbolKeys<string>` and `StripSymbolKeys<number>` to both resolve to `{}`, so `IsEqualIgnoringBrands<string, number>` returns `true` and transforms on primitive fields are silently allowed.
</issue>
</file>

Tag @mendral-app with feedback or questions. View session

Comment on lines +208 to +210
type StripSymbolKeys<T> = {
[K in keyof T as K extends symbol ? never : K]: StripSymbolKeys<T[K]>;
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

bug (P0): Missing base case for primitives causes StripSymbolKeys<string> and StripSymbolKeys<number> to both resolve to {}, so IsEqualIgnoringBrands<string, number> returns true and transforms on primitive fields are silently allowed.

Suggested change
Suggested change
type StripSymbolKeys<T> = {
[K in keyof T as K extends symbol ? never : K]: StripSymbolKeys<T[K]>;
};
type StripSymbolKeys<T> = T extends object
? { [K in keyof T as K extends symbol ? never : K]: StripSymbolKeys<T[K]> }
: T;
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/inngest/src/components/triggers/triggers.ts, line 208:

<issue>
Missing base case for primitives causes `StripSymbolKeys<string>` and `StripSymbolKeys<number>` to both resolve to `{}`, so `IsEqualIgnoringBrands<string, number>` returns `true` and transforms on primitive fields are silently allowed.
</issue>

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

Labels

📦 inngest Affects the `inngest` package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants