Skip to content

[BUGFIX beta] Fix 'on' modifier error message regression#21091

Open
crazylogic03 wants to merge 9 commits intoemberjs:mainfrom
crazylogic03:fix/on-modifier-error-message
Open

[BUGFIX beta] Fix 'on' modifier error message regression#21091
crazylogic03 wants to merge 9 commits intoemberjs:mainfrom
crazylogic03:fix/on-modifier-error-message

Conversation

@crazylogic03
Copy link

@crazylogic03 crazylogic03 commented Feb 15, 2026

This PR fixes a regression where the helpful error message for the 'on' modifier was lost when the callback is undefined or not a function.

It adds an explicit runtime check in DEBUG mode to ensure the callback is a function, and includes a reproduction test case to verify the fix.

This restores the helpful error message when the 'on' modifier is used without a function callback, which was lost in a recent refactor.
Copy link
Author

@crazylogic03 crazylogic03 left a comment

Choose a reason for hiding this comment

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

I have implemented a fix to restore the helpful error message when the

on
modifier is used without a function callback.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 15, 2026

Estimated Asset Sizes

Diff

--- main/out.txt	2026-02-13 16:38:38.000000000 +0000
+++ pr/./pr-22039263969/out.txt	2026-02-15 16:43:00.000000000 +0000
@@ -1,16 +1,16 @@
 ╔═══════╤═══════════╤═══════════╗
 ║       │ Min       │ Gzip      ║
 ╟───────┼───────────┼───────────╢
-║ Total │ 352.02 KB │ 203.77 KB ║
+║ Total │ 352.02 KB │ 203.83 KB ║
 ╚═══════╧═══════════╧═══════════╝
 
 ╔══════════════════════╤═══════════╤═══════════╗
 ║ @ember/*             │ Min       │ Gzip      ║
 ╟──────────────────────┼───────────┼───────────╢
-║ Total                │ 313.42 KB │ 181.95 KB ║
+║ Total                │ 313.42 KB │ 181.89 KB ║
 ╟──────────────────────┼───────────┼───────────╢
-║ -internals           │ 36.65 KB  │ 26.23 KB  ║
-║ application          │ 13.23 KB  │ 8.09 KB   ║
+║ -internals           │ 36.65 KB  │ 26.22 KB  ║
+║ application          │ 13.23 KB  │ 8.05 KB   ║
 ║ array                │ 13.01 KB  │ 7.46 KB   ║
 ║ canary-features      │ 304 B     │ 389 B     ║
 ║ component            │ 2.05 KB   │ 1.64 KB   ║
@@ -19,16 +19,16 @@
 ║ deprecated-features  │ 31 B      │ 77 B      ║
 ║ destroyable          │ 561 B     │ 383 B     ║
 ║ enumerable           │ 259 B     │ 387 B     ║
-║ helper               │ 1.08 KB   │ 803 B     ║
+║ helper               │ 1.08 KB   │ 811 B     ║
 ║ instrumentation      │ 2.43 KB   │ 1.79 KB   ║
-║ modifier             │ 1.22 KB   │ 966 B     ║
+║ modifier             │ 1.22 KB   │ 965 B     ║
 ║ object               │ 35.94 KB  │ 22.16 KB  ║
 ║ owner                │ 159 B     │ 178 B     ║
-║ renderer             │ 630 B     │ 492 B     ║
-║ routing              │ 59.33 KB  │ 34.13 KB  ║
+║ renderer             │ 630 B     │ 487 B     ║
+║ routing              │ 59.33 KB  │ 34.1 KB   ║
 ║ runloop              │ 2.36 KB   │ 1.5 KB    ║
 ║ service              │ 1 KB      │ 845 B     ║
-║ template             │ 654 B     │ 519 B     ║
+║ template             │ 654 B     │ 541 B     ║
 ║ template-compilation │ 429 B     │ 366 B     ║
 ║ template-compiler    │ 123.08 KB │ 59.45 KB  ║
 ║ template-factory     │ 370 B     │ 374 B     ║
@@ -40,19 +40,19 @@
 ╔═════════════════╤══════════╤══════════╗
 ║ @glimmer/*      │ Min      │ Gzip     ║
 ╟─────────────────┼──────────┼──────────╢
-║ Total           │ 38.6 KB  │ 21.82 KB ║
+║ Total           │ 38.6 KB  │ 21.94 KB ║
 ╟─────────────────┼──────────┼──────────╢
 ║ destroyable     │ 2.77 KB  │ 1.39 KB  ║
 ║ encoder         │ 81 B     │ 171 B    ║
 ║ env             │ 38 B     │ 87 B     ║
 ║ global-context  │ 886 B    │ 545 B    ║
 ║ manager         │ 977 B    │ 608 B    ║
-║ node            │ 175 B    │ 245 B    ║
+║ node            │ 175 B    │ 260 B    ║
 ║ opcode-compiler │ 1.11 KB  │ 894 B    ║
 ║ owner           │ 159 B    │ 202 B    ║
 ║ program         │ 252 B    │ 301 B    ║
 ║ reference       │ 548 B    │ 531 B    ║
-║ runtime         │ 10.32 KB │ 5.22 KB  ║
+║ runtime         │ 10.32 KB │ 5.32 KB  ║
 ║ tracking        │ 1.34 KB  │ 1.16 KB  ║
 ║ util            │ 1.94 KB  │ 1.68 KB  ║
 ║ validator       │ 15.75 KB │ 6.96 KB  ║

Details

This PRmain
╔═══════╤═══════════╤═══════════╗
║       │ Min       │ Gzip      ║
╟───────┼───────────┼───────────╢
║ Total │ 352.02 KB │ 203.83 KB ║
╚═══════╧═══════════╧═══════════╝

╔══════════════════════╤═══════════╤═══════════╗
║ @ember/*             │ Min       │ Gzip      ║
╟──────────────────────┼───────────┼───────────╢
║ Total                │ 313.42 KB │ 181.89 KB ║
╟──────────────────────┼───────────┼───────────╢
║ -internals           │ 36.65 KB  │ 26.22 KB  ║
║ application          │ 13.23 KB  │ 8.05 KB   ║
║ array                │ 13.01 KB  │ 7.46 KB   ║
║ canary-features      │ 304 B     │ 389 B     ║
║ component            │ 2.05 KB   │ 1.64 KB   ║
║ controller           │ 1.96 KB   │ 1.41 KB   ║
║ debug                │ 11.69 KB  │ 8.12 KB   ║
║ deprecated-features  │ 31 B      │ 77 B      ║
║ destroyable          │ 561 B     │ 383 B     ║
║ enumerable           │ 259 B     │ 387 B     ║
║ helper               │ 1.08 KB   │ 811 B     ║
║ instrumentation      │ 2.43 KB   │ 1.79 KB   ║
║ modifier             │ 1.22 KB   │ 965 B     ║
║ object               │ 35.94 KB  │ 22.16 KB  ║
║ owner                │ 159 B     │ 178 B     ║
║ renderer             │ 630 B     │ 487 B     ║
║ routing              │ 59.33 KB  │ 34.1 KB   ║
║ runloop              │ 2.36 KB   │ 1.5 KB    ║
║ service              │ 1 KB      │ 845 B     ║
║ template             │ 654 B     │ 541 B     ║
║ template-compilation │ 429 B     │ 366 B     ║
║ template-compiler    │ 123.08 KB │ 59.45 KB  ║
║ template-factory     │ 370 B     │ 374 B     ║
║ test                 │ 923 B     │ 627 B     ║
║ utils                │ 4.11 KB   │ 3.6 KB    ║
║ version              │ 55 B      │ 131 B     ║
╚══════════════════════╧═══════════╧═══════════╝

╔═════════════════╤══════════╤══════════╗
║ @glimmer/*      │ Min      │ Gzip     ║
╟─────────────────┼──────────┼──────────╢
║ Total           │ 38.6 KB  │ 21.94 KB ║
╟─────────────────┼──────────┼──────────╢
║ destroyable     │ 2.77 KB  │ 1.39 KB  ║
║ encoder         │ 81 B     │ 171 B    ║
║ env             │ 38 B     │ 87 B     ║
║ global-context  │ 886 B    │ 545 B    ║
║ manager         │ 977 B    │ 608 B    ║
║ node            │ 175 B    │ 260 B    ║
║ opcode-compiler │ 1.11 KB  │ 894 B    ║
║ owner           │ 159 B    │ 202 B    ║
║ program         │ 252 B    │ 301 B    ║
║ reference       │ 548 B    │ 531 B    ║
║ runtime         │ 10.32 KB │ 5.32 KB  ║
║ tracking        │ 1.34 KB  │ 1.16 KB  ║
║ util            │ 1.94 KB  │ 1.68 KB  ║
║ validator       │ 15.75 KB │ 6.96 KB  ║
║ vm              │ 495 B    │ 569 B    ║
║ wire-format     │ 1.84 KB  │ 1.35 KB  ║
╚═════════════════╧══════════╧══════════╝
╔═══════╤═══════════╤═══════════╗
║       │ Min       │ Gzip      ║
╟───────┼───────────┼───────────╢
║ Total │ 352.02 KB │ 203.77 KB ║
╚═══════╧═══════════╧═══════════╝

╔══════════════════════╤═══════════╤═══════════╗
║ @ember/*             │ Min       │ Gzip      ║
╟──────────────────────┼───────────┼───────────╢
║ Total                │ 313.42 KB │ 181.95 KB ║
╟──────────────────────┼───────────┼───────────╢
║ -internals           │ 36.65 KB  │ 26.23 KB  ║
║ application          │ 13.23 KB  │ 8.09 KB   ║
║ array                │ 13.01 KB  │ 7.46 KB   ║
║ canary-features      │ 304 B     │ 389 B     ║
║ component            │ 2.05 KB   │ 1.64 KB   ║
║ controller           │ 1.96 KB   │ 1.41 KB   ║
║ debug                │ 11.69 KB  │ 8.12 KB   ║
║ deprecated-features  │ 31 B      │ 77 B      ║
║ destroyable          │ 561 B     │ 383 B     ║
║ enumerable           │ 259 B     │ 387 B     ║
║ helper               │ 1.08 KB   │ 803 B     ║
║ instrumentation      │ 2.43 KB   │ 1.79 KB   ║
║ modifier             │ 1.22 KB   │ 966 B     ║
║ object               │ 35.94 KB  │ 22.16 KB  ║
║ owner                │ 159 B     │ 178 B     ║
║ renderer             │ 630 B     │ 492 B     ║
║ routing              │ 59.33 KB  │ 34.13 KB  ║
║ runloop              │ 2.36 KB   │ 1.5 KB    ║
║ service              │ 1 KB      │ 845 B     ║
║ template             │ 654 B     │ 519 B     ║
║ template-compilation │ 429 B     │ 366 B     ║
║ template-compiler    │ 123.08 KB │ 59.45 KB  ║
║ template-factory     │ 370 B     │ 374 B     ║
║ test                 │ 923 B     │ 627 B     ║
║ utils                │ 4.11 KB   │ 3.6 KB    ║
║ version              │ 55 B      │ 131 B     ║
╚══════════════════════╧═══════════╧═══════════╝

╔═════════════════╤══════════╤══════════╗
║ @glimmer/*      │ Min      │ Gzip     ║
╟─────────────────┼──────────┼──────────╢
║ Total           │ 38.6 KB  │ 21.82 KB ║
╟─────────────────┼──────────┼──────────╢
║ destroyable     │ 2.77 KB  │ 1.39 KB  ║
║ encoder         │ 81 B     │ 171 B    ║
║ env             │ 38 B     │ 87 B     ║
║ global-context  │ 886 B    │ 545 B    ║
║ manager         │ 977 B    │ 608 B    ║
║ node            │ 175 B    │ 245 B    ║
║ opcode-compiler │ 1.11 KB  │ 894 B    ║
║ owner           │ 159 B    │ 202 B    ║
║ program         │ 252 B    │ 301 B    ║
║ reference       │ 548 B    │ 531 B    ║
║ runtime         │ 10.32 KB │ 5.22 KB  ║
║ tracking        │ 1.34 KB  │ 1.16 KB  ║
║ util            │ 1.94 KB  │ 1.68 KB  ║
║ validator       │ 15.75 KB │ 6.96 KB  ║
║ vm              │ 495 B    │ 569 B    ║
║ wire-format     │ 1.84 KB  │ 1.35 KB  ║
╚═════════════════╧══════════╧══════════╝

@NullVoxPopuli
Copy link
Contributor

@crazylogic03 looks like tests don't pass

@NullVoxPopuli
Copy link
Contributor

@crazylogic03 can you show a before and after of what you see in the browser after making this change? (for the changelog, it would be helpful to know what the specific problem being solved is) tyty!

@crazylogic03
Copy link
Author

@NullVoxPopuli
Specific Problem:
In recent versions (since 5.12), passing a non-function (like undefined or null) to the on modifier resulted in unhelpful or generic errors, making it hard to track down where the invalid value came from.

Before:
The validation was either missing or generic assertion failures that didn't help pinpoint the issue.

After:
The modifier now explicitly checks the callback type in DEBUG mode and throws a descriptive error including the type received and the debug label of the argument.
Example Error:
You must pass a function as the second argument to the 'on' modifier; you passed undefined. While rendering: ...

@NullVoxPopuli
Copy link
Contributor

@crazylogic03 legit thanks for looking in to this! new error phrasing looks good. what was the old error?

@NullVoxPopuli
Copy link
Contributor

Looks like on 6.10, we get "Cannot access bind of undefined" (not good lol)

@crazylogic03
Copy link
Author

@NullVoxPopuli Yep, exactly!
The old error Cannot read properties of undefined (reading 'bind') happened because we were trying to .bind() the callback for debug context before actually verifying it was a function.
This PR adds an explicit check before that point, so instead of crashing with a native JS error, we now get a helpful Ember assertion telling you exactly what argument was passed (e.g. undefined or null) and where.

@crazylogic03
Copy link
Author

@NullVoxPopuli Can You Review merge this PR and All the Checks have passed

@crazylogic03
Copy link
Author

Thanks for the review @NullVoxPopuli! I'm glad we could get this fixed.

@crazylogic03
Copy link
Author

@kategengler Can You Review merge this PR and All the Checks have passed 🙂

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.

3 participants